BlazorWebView を使用して .NET MAUI アプリで Blazor Web アプリをホストする
.NET マルチプラットフォーム アプリ UI (.NET MAUI) BlazorWebView は、.NET MAUI アプリで Blazor Web アプリをホストできるようにするコントロールです。 Blazor ハイブリッド アプリと呼ばれるこれらのアプリを使用すると、Blazor Web アプリをプラットフォームの機能や UI コントロールと統合できます。 BlazorWebView コントロールは、.NET MAUI アプリの任意のページに追加でき、Blazor アプリのルートを指すことができます。 Razor コンポーネント は、.NET プロセスでネイティブに動作し、Web UI を埋め込み Web ビュー コントロールにレンダリングします。 .NET MAUI では、Blazor ハイブリッド アプリは、.NET MAUI でサポートされているすべてのプラットフォームで実行できます。
BlazorWebView には、次のプロパティが定義されています。
string?
型の HostPage は、Blazor Web アプリのルート ページを定義します。RootComponentsCollection
型の RootComponents は、コントロールに追加できるルート コンポーネントのコレクションを指定します。string
型の StartPath は、Blazor コンポーネントの読み込みが完了したときの、Blazor ナビゲーション コンテキスト内の最初のナビゲーションのパスを定義します。
RootComponent クラスには、次のプロパティが定義されています。
string?
型の Selector は、ドキュメント内のコンポーネントを配置する場所を指定する CSS セレクター文字列を定義します。Type?
型の ComponentType は、ルート コンポーネントの型を定義します。IDictionary<string, object?>?
型の Parameters は、ルート コンポーネントに渡すパラメーターのディクショナリ (オプション) を表します。
また、BlazorWebView では次のイベントが定義されます。
- BlazorWebViewInitializing には、BlazorWebView が初期化される前に生成される
BlazorWebViewInitializingEventArgs
オブジェクトが伴います。 このイベントにより、BlazorWebView 構成のカスタマイズが可能になります。 - BlazorWebViewInitialized には、付随する
BlazorWebViewInitializedEventArgs
オブジェクトが含まれます。このオブジェクトは、BlazorWebView が初期化された後、コンポーネントがレンダリングされる前に発生します。 このイベントにより、プラットフォーム固有の Web ビュー インスタンスの取得が可能になります。 - UrlLoading は、
UrlLoadingEventArgs
オブジェクトを伴い、BlazorWebView 内でハイパーリンクがクリックされると発生します。 このイベントにより、ハイパーリンクを BlazorWebView で開くか、外部アプリで開くか、または URL の読み込み試行をキャンセルするかどうかをカスタマイズできます。
既存の Razor コンポーネント は、コードをアプリに移動するか、コンポーネントを含む既存のクラス ライブラリまたはパッケージを参照すれば、.NET MAUI Blazor アプリで使用できます。 詳細については、「ASP.NET Core Blazor Hybrid での Razor コンポーネントの再利用」をご覧ください。
ブラウザー開発者ツールを使用して、.NET MAUI Blazor アプリを検査できます。 詳細については、「ASP.NET Core Blazor Hybrid でブラウザー開発者ツールを使用する」をご覧ください。
Note
Visual Studio は .NET MAUI Blazor アプリの開発に必要なツールをすべてインストールしますが、Windows 上の .NET MAUI Blazor アプリのエンド ユーザーは WebView2 ランタイムをインストールする必要があります。
Blazor Hybrid アプリの詳細については、「ASP.NET Core Blazor Hybrid」をご覧ください。
.NET MAUI Blazor アプリを作成する
.NET MAUI Blazor アプリは、.NET MAUI Blazor アプリ テンプレートを使用して Visual Studio で作成できます。
このプロジェクト テンプレートでは、Android、iOS、macOS、Windows にデプロイできる複数ターゲットの .NET MAUI Blazor アプリが作成されます。 .NET MAUI Blazor アプリの作成手順については、「.NET MAUI Blazor アプリの構築」をご覧ください。
プロジェクト テンプレートによって作成された BlazorWebView は MainPage.xaml で定義され、Blazor アプリのルートを指します。
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:BlazorWebViewDemo"
x:Class="BlazorWebViewDemo.MainPage"
BackgroundColor="{DynamicResource PageBackgroundColor}">
<BlazorWebView HostPage="wwwroot/index.html">
<BlazorWebView.RootComponents>
<RootComponent Selector="#app" ComponentType="{x:Type local:Main}" />
</BlazorWebView.RootComponents>
</BlazorWebView>
</ContentPage>
アプリのルート Razor コンポーネントは Main.razor にあり、Razor はこれをアプリケーションのルート名前空間の Main
という名前の型にコンパイルします。 残りの Razor コンポーネントは、ページ および Shared プロジェクト フォルダーにあり、既定の Blazor Web テンプレートで使用されるコンポーネントと同じです。 アプリの静的 Web アセットは wwwroot フォルダーにあります。
BlazorWebView を既存のアプリに追加する
既存の .NET MAUI アプリに BlazorWebView を追加するプロセスは次のとおりです。
CSPROJ プロジェクト ファイルの最初の行を編集して、Razor SDK
Microsoft.NET.Sdk.Razor
をプロジェクトに追加します。<Project Sdk="Microsoft.NET.Sdk.Razor">
Razor SDK は、Blazor プロジェクト用の Razor ファイルを含んだプロジェクトのビルドとパッケージ化に必要です。
アプリのルート Razor コンポーネントをプロジェクトに追加します。
Razor コンポーネントをページと共有という名前のプロジェクト フォルダに追加します。
静的ウェブアセットを wwwroot という名前のプロジェクト フォルダに追加します。
省略可能な _Imports.razor ファイルをプロジェクトに追加します。
.NET MAUI アプリのページに BlazorWebView を追加し、Blazor アプリのルートをポイントします。
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:MyBlazorApp" x:Class="MyBlazorApp.MainPage"> <BlazorWebView HostPage="wwwroot/index.html"> <BlazorWebView.RootComponents> <RootComponent Selector="#app" ComponentType="{x:Type local:Main}" /> </BlazorWebView.RootComponents> </BlazorWebView> </ContentPage>
MauiProgram
クラスのCreateMauiApp
メソッドを変更して、アプリで使用する BlazorWebView コントロールを登録します。 これを行うには、IServiceCollection オブジェクトでAddMauiBlazorWebView
メソッドを呼び出して、コンポーネント Web ビュー サービスをサービス コレクションに追加します。public static class MauiProgram { public static MauiApp CreateMauiApp() { var builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .ConfigureFonts(fonts => { fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); }); builder.Services.AddMauiBlazorWebView(); #if DEBUG builder.Services.AddBlazorWebViewDeveloperTools(); #endif // Register any app services on the IServiceCollection object // e.g. builder.Services.AddSingleton<WeatherForecastService>(); return builder.Build(); } }
このコードでは、アプリがデバッグ構成で実行されているときに、基になる WebView コントロールの開発者ツールも有効になります。
ネイティブ UI からスコープ付きサービスにアクセスする
BlazorWebView には、指定された Action<ServiceProvider>
を非同期で呼び出し、Razor コンポーネントで利用可能なスコープ指定されたサービスを渡すことができる TryDispatchAsync メソッドがあります。 これを使うと、ネイティブ UI のコードから NavigationManager などのスコープ付きサービスにアクセスできます。
private async void OnMyMauiButtonClicked(object sender, EventArgs e)
{
var wasDispatchCalled = await blazorWebView.TryDispatchAsync(sp =>
{
var navMan = sp.GetRequiredService<NavigationManager>();
navMan.CallSomeNavigationApi(...);
});
if (!wasDispatchCalled)
{
// Consider what to do if it the dispatch fails - that's up to your app to decide.
}
}
問題の診断
BlazorWebView には、Blazor Hybrid アプリの問題を診断するのに役立つ組み込みのログ記録があります。 このログ記録を有効にするには、次の 2 つの手順があります。
- 診断情報をログに記録するために、BlazorWebView と関連コンポーネントを有効にする。
- ログ出力を表示できる場所に書き込むようにロガーを構成します。
ログ記録に関する詳細については、「C# と .NET でのログ記録」をご覧ください。
BlazorWebView のログ記録を有効にする
すべてのログ記録構成は、依存関係挿入システムのサービス登録の一部として実行できます。 Microsoft.AspNetCore.Components.WebView 名前空間の BlazorWebView と関連コンポーネントの最大ログを有効にするには、アプリのサービスが登録されている場所に次のコードを追加します。
services.AddLogging(logging =>
{
logging.AddFilter("Microsoft.AspNetCore.Components.WebView", LogLevel.Trace);
});
または、Microsoft.Extensions.Logging を使用するすべてのコンポーネントの最大ログを有効にするには、次のコードを使用します。
services.AddLogging(logging =>
{
logging.SetMinimumLevel(LogLevel.Trace);
});
ログ出力の構成と出力の表示
ログ情報を書き込むコンポーネントを構成した後、ロガーがログ情報を書き込む場所を構成し、次にログの出力を表示する必要があります。
デバッグ ログ プロバイダーは、Debug
ステートメントを使用して出力を書き込み、出力は Visual Studio から表示できます。
デバッグ ログ プロバイダーを構成するには、まずプロジェクトのリファレンスを Microsoft.Extensions.Logging.Debug
NuGet パッケージに追加します。 次に、AddDebug 拡張メソッドを呼び出して、前の手順で追加した AddLogging の呼び出し内にプロバイダーを登録します。
services.AddLogging(logging =>
{
logging.AddFilter("Microsoft.AspNetCore.Components.WebView", LogLevel.Trace);
logging.AddDebug();
});
デバッグが有効になっている Visual Studio からアプリを実行すると、Visual Studio の [出力] ウィンドウにデバッグ出力が表示されます。
iOS でインライン ビデオを再生する
iOS 上の Blazor ハイブリッド アプリでインライン ビデオを再生するには、BlazorWebView で以下を行う必要があります。
UrlLoadingStrategy プロパティを
OpenInWebView
に設定します。 これは、UrlLoading イベントのイベント ハンドラーで実行できます。private void BlazorUrlLoading(object? sender, UrlLoadingEventArgs e) { #if IOS e.UrlLoadingStrategy = UrlLoadingStrategy.OpenInWebView; #endif }
Configuration
オブジェクトのAllowsInlineMediaPlayback
プロパティがtrue
に設定されていることを確認します。 これは、BlazorWebViewInitializing イベントのイベント ハンドラーで実行できます。private void BlazorWebViewInitializing(object? sender, BlazorWebViewInitializingEventArgs e) { #if IOS e.Configuration.AllowsInlineMediaPlayback = true; #endif }
Android での破棄デッドロック
既定では、 BlazorWebView は起動し、基になる WebViewManager
の非同期破棄を忘れています。 これにより、Android で破棄デッドロックが発生する可能性が減少します。
警告
このファイア アンド フォーゲットの既定の動作は、すべてのオブジェクトが破棄される前に破棄を返すことができることを意味します。これにより、アプリの動作が変更される可能性があります。 破棄される項目は、部分的には Blazor 独自の内部型ですが、アプリの BlazorWebView 部分で使用されるスコープ サービスなどのアプリ定義型でもあります。
この動作をオプトアウトするには、MauiProgram
クラスの CreateMauiApp
メソッドの AppContext スイッチを介して dispose をブロックするようにアプリを構成する必要があります。
AppContext.SetSwitch("BlazorWebView.AndroidFireAndForgetAsync", false);
このスイッチを介して破棄時にブロックするようにアプリが構成されている場合、 BlazorWebView は非同期の過剰同期破棄を実行します。つまり、非同期破棄が完了するまでスレッドがブロックされます。 ただし、破棄が同じスレッドでコードを実行する必要がある場合、デッドロックが発生する可能性があります (待機中にスレッドがブロックされるため)。
iOS および Mac Catalyst で従来の動作を使用してコンテンツをホストする
iOS および Mac Catalyst 18 では、BlazorWebView 内のコンテンツをホストするための既定の動作が localhost
に変更されています。 コンテンツをホストするために使用される内部 0.0.0.1
アドレスは機能しなくなり、その結果、BlazorWebView にはコンテンツが読み込まれず、空の四角形としてレンダリングされます。
0.0.0.1
アドレスの使用をオプトインするには、MauiProgram.cs の CreateMauiApp
メソッドに次のコードを追加します。
// Set this switch to use the LEGACY behavior of always using 0.0.0.1 to host BlazorWebView
AppContext.SetSwitch("BlazorWebView.AppHostAddressAlways0000", true);
.NET MAUI