LoginSignup
4
7

.NET 8 で ASP.NET Core でホストされた Blazor WebAssembly アプリを作成する

Last updated at Posted at 2024-04-09

やりたいこと

  • .NET 8 で、.NET 7 以前はできた ASP.NET Core でホストされた Blazor WebAssembly アプリを作成する

環境

  • Windows 11 23H2
  • Visual Studio Community 2022 Version 17.9.5

手順

準備

  1. 空のソリューションを追加
    1. {ソリューション名}
  2. Blazor WebAssembly アプリ プロジェクトを追加
    image.png
    1. {ソリューション名}.UI.Client
    2. .NET 8 を選択、その他はそのまま
      image.png
    3. デバッグ実行確認
      image.png
  3. ASP.NET Core Web API プロジェクトを追加
    image.png
    1. {ソリューション名}.UI.Server
    2. .NET 8 を選択、その他はそのまま
      image.png
    3. デバッグ実行確認(Swawgger が開く)
      image.png
  4. クラスライブラリ プロジェクトを追加
    image.png
    1. {ソリューション名}.UI.Share
    2. .NET 8 を選択
      image.png

作成したプロジェクト構成

  • {ソリューション名}
    • {ソリューション名}.UI.Client
      • クライアントアプリ
    • {ソリューション名}.UI.Server
      • API
    • {ソリューション名}.UI.Share
      • クライアントアプリとAPIの間でやり取りするオブジェクト等

Server の変更

NuGet パッケージを追加

  1. Microsoft.AspNetCore.Components.WebAssembly.Server

依存関係追加

  1. Client
  2. Share

Program.cs の変更

Program.cs
- builder.Services.AddControllers();
+ builder.Services.AddControllersWithViews();
+ builder.Services.AddRazorPages();
Program.cs
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
+   app.UseWebAssemblyDebugging();
}
Program.cs
app.UseHttpsRedirection();

+ app.UseBlazorFrameworkFiles();
+ app.UseStaticFiles();
Program.cs
+ app.MapRazorPages();
app.MapControllers();
+ app.MapFallbackToFile("index.html");
Program.cs(完成)
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
    app.UseWebAssemblyDebugging();
}

app.UseHttpsRedirection();

app.UseBlazorFrameworkFiles();
app.UseStaticFiles();

app.UseAuthorization();

app.MapRazorPages();
app.MapControllers();
app.MapFallbackToFile("index.html");

app.Run();

動作確認

  • スタートアッププロジェクトに Server を設定しデバッグ実行
  • Swagger が開く・・・!
    image.png

Swagger が開かないようにする

  1. launchSettings.json を開く
  2. 書く環境に設定されている "launchUrl": "swagger","inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", に置換

動作確認

  • デバッグ実行
  • Blazor WebAssembly アプリが起動した!
    image.png

Client の変更

依存関係追加

  • Share

Weather.razor から Server の API を叩く

Weather.razor
    protected override async Task OnInitializedAsync()
    {
-       forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("sample-data/weather.json");
+       forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("weatherforecast");
    }

Share を使うように変更

Share に WeatherForecast クラスを追加

このクラスを Client/Server 両方から使います。

WeatherForecast.cs
+ namespace SolutionName.UI.Share.WeatherForecastModels;
+
+ public class WeatherForecast
+ {
+     public DateOnly Date { get; set; }
+
+     public int TemperatureC { get; set; }
+
+     public string? Summary { get; set; }
+
+     public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
+ }

Client の WeatherForecast クラスを削除

Weather.razor
@code {
    private WeatherForecast[]? forecasts;

    protected override async Task OnInitializedAsync()
    {
        forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("weatherforecast");
    }
    
-   public class WeatherForecast
-   {
-       public DateOnly Date { get; set; }
-
-       public int TemperatureC { get; set; }
-
-       public string? Summary { get; set; }
-
-       public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
-   }
}

Client に using 追加

Weather.razor
@page "/weather"
+ @using SolutionName.UI.Share.WeatherForecastModels
@inject HttpClient Http

Server の WeatherForecast クラスを削除

WeatherForecast.cs
- namespace HigeDaruma.DemoNet8BlazorWasm.UI.Server;
-
- public class WeatherForecast
- {
-     public DateOnly Date { get; set; }
-
-     public int TemperatureC { get; set; }
-
-     public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
-
-     public string? Summary { get; set; }
- }

Server に using 追加

WeatherForecast.cs
+ using SolutionName.UI.Share.WeatherForecastModels;
using Microsoft.AspNetCore.Mvc;

動作確認

取得成功!
image.png

ついでに C# 12 の新機能を使う

コレクションの初期化を簡素化する

WeatherForecastController.cs
-     private static readonly string[] Summaries = new[]
-     {
-         "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", - "Sweltering", "Scorching"
-     };
+     private static readonly string[] Summaries =
+     [
+         "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
+     ];

プライマリーコンストラクターを使う(そしてフィールドを削除する)

WeatherForecastController.cs
- public class WeatherForecastController : ControllerBase
+ public class WeatherForecastController(ILogger<WeatherForecastController> logger) : ControllerBase
{
    private static readonly string[] Summaries =
    [
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    ];

-     private readonly ILogger<WeatherForecastController> _logger;
-
-     public WeatherForecastController(ILogger<WeatherForecastController> logger)
-     {
-         _logger = logger;
-     }

おわりに

.NET 8 に ASP.NET Core でホストされた Blazor WebAssembly アプリは追加されないんですかね。Blazor でクライアントを作る単一ソリューションのアプリだと API 層があった方がレイヤードアーキテクチャーを構成しやすいんですけど。
次回この続きでレイヤードアーキテクチャーを実現していこうと思います。


参考

4
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
7