Blazor Wasm でない ASP.NET Core アプリを PWA 化する

# やりたいこと
- ASP.NET Core で作った Web アプリを PWA 化する
- Blazor Wasm は使わない

# 環境
- Visual Studio Community 2022
    - Version 17.11.2
- .NET 8(C#12)

# 使うパッケージ
### WebEssentials.AspNetCore.PWA

https://github.com/madskristensen/WebEssentials.AspNetCore.ServiceWorker

JavaScript の実装なしに C# のみで実現できます。設定方法もここに書いてある通りにやればOKです。

# やったこと
## ASP.NET Core MVC アプリの PWA 化

### ASP.NET Core MVC アプリケーションの作成
テンプレートプロジェクトを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/37f75820-7b98-deee-843f-9f4e605ea429.png)

実行してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/6f149a8d-7a79-25e8-5df8-ae7b6efcc5a5.png)

### NuGet パッケージの追加
NuGet パッケージの管理から WebEssentials.AspNetCore.PWA をインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/a3db3ec6-d481-9eb8-443f-b192ff9d5e13.png)

### アイコンファイルを追加
1. icon192x192 と icon512x512 ふたつのファイルを用意します
    1. jpeg/png
    1. ファイル名は調整できます
1. `wwwroot/img` に配置します
    1. 場所は調整できます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/b4f1aa30-d284-3694-1456-71365d244387.png)

### マニフェストファイルを追加
- `wwwroot` に `manifest.json` を追加します
```json:manifest.json
{
  "name": "<アプリ名>",
  "short_name": "<アプリ名の短縮形>",
  "description": "<アプリの説明>",
  "icons": [
    {
      "src": "/img/icon192x192.png",
      "sizes": "192x192"
    },
    {
      "src": "/img/icon512x512.png",
      "sizes": "512x512"
    }
  ],
  "display": "standalone",
  "start_url": "/"
}
```

### Program.cs で設定

```diff_c_sharp:Program.cs
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();
+builder.Services.AddProgressiveWebApp();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();
```

### デバッグ実行
アドレスバーにインストールボタンが追加されました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/723deda6-0239-def1-5f2e-3c7bcb94c480.png)

アイコンとアプリ名が表示されるのでインストールを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/aaa490a3-f47f-a5c0-3903-124fc6739236.png)

インストールされました。ブラウザの要素がなくなり、まるでネイティブアプリのようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/863fd1cc-0ff3-f415-873a-e38d82a33c48.png)

タスクバーにピン止めもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/3d5755b2-eb90-1b82-ea01-7e685977261d.png)


## ASP.NET Core Web アプリ（Razor Pages）
ASP.NET Core Web アプリ でも同様に PWA 化できますが、少し手を加える必要があるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/475db47f-0076-e615-2186-0b6c0a83bbe3.png)
以下のようにマニフェストファイルを指定してやることでインストールボタンが現れました。
```diff_c_sharp
<head>
    :
+    <link rel="manifest" href="/manifest.json">
</head>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/ababaa58-7a33-9bd1-97e1-163e9e5483cc.png)

# まとめ
Blazor Wasm プロジェクトでは標準で PWA 化することができますが、ASP.NET Core Web アプリでも簡単に PWA 化することができました。PWA 化することで Web アプリをネイティブアプリのように使うことができます。オフライン時の表示など課題はありますが、本当に簡単に実現できました。