先に結論
System.OperatingSystem.IsBrowser()
を実行してください。true
が返る場合は、ブラウザ上で (いわゆる Blazor WebAssembly として) 実行されています。
背景
Blazor には Blazor WebAssembly、Blazor Server の基本2形態があり、さらに 2023年11月リリースの .NET 8 からは、Blazor Static Server Side Rendering が加わりました。このように、Blazor は、サーバー側プロセスとして実行される場合と、Web ブラウザ内の WebAssembly 上で実行される場合の、2つの場合があります。
また、一般に Blazor WebAssembly に分類される場合でも、サーバー側事前レンダリングを実装していると、その事前レンダリング処理はサーバー側プロセスで実行されます。.NET 8 のリリースにともない、"Auto レンダーモード" の登場や、標準のプロジェクトテンプレートが生成するプロジェクトで事前レンダリングが既定で有効になっていることによって、ますます、同じコンポーネント実装が、サーバー側とブラウザ側の両方で実行されうる機会が増えました。
Blazor のコンポーネント (Razor コンポーネント) の実装にあたっては、基本的には Microsoft 公式ドキュメントのガイドラインに沿っていれば、サーバー側でもブラウザ側でも、どちらでも問題なく動作するようにできあがります。とはいえ、いくつかのエッジケースでは、今現在、サーバー側で実行されているのか、ブラウザ上で実行されているのかを判定したいケースがでてくるでしょう。
そうしたときに、具体的には、どのようなコードを書けば、サーバー側とブラウザ側のどちらで実行されているのかを知ることができるのでしょうか。
検証
実行時のプラットフォーム環境に関する各種情報は、System.Runtime.InteropServices
名前空間の RuntimeInformation
クラスや System.Environment
クラス、そして System.OperatingSystem
クラスから公開されているメンバーを介して様々知ることができます。
そこで、それらメンバーの値を表示する以下のコンポーネントを実装し、
@using System.Runtime.InteropServices
<div>
<dt>OperatingSystem.IsBrowser()</dt>
<dd>@OperatingSystem.IsBrowser()</dd>
<dt>Framework Description</dt>
<dd>@RuntimeInformation.FrameworkDescription</dd>
<dt>Process Architecture</dt>
<dd>@RuntimeInformation.ProcessArchitecture</dd>
<dt>OS Architecture</dt>
<dd>@RuntimeInformation.OSArchitecture</dd>
<dt>OS Description</dt>
<dd>@RuntimeInformation.OSDescription</dd>
<dt>OS Platform</dt>
<dd>@Environment.OSVersion.Platform</dd>
<dt>OS Version</dt>
<dd>@Environment.OSVersion.Version</dd>
<dt>OS Version ServicePack</dt>
<dd>@Environment.OSVersion.ServicePack</dd>
</div>
このコンポーネントを Blazor Sever と Blazor WebAssembly のそれぞれで実行して、どのように表示されるかを確認してみました。
Blazor Server 上での実行結果
メンバー | 値 |
---|---|
OperatingSystem.IsBrowser() | False |
Framework Description | .NET 8.0.0 |
Process Architecture | X64 |
OS Architecture | X64 |
OS Description | Microsoft Windows 10.0.22631 |
OS Platform | Win32NT |
OS Version | 10.0.22631.0 |
OS Version ServicePack |
※上記結果は自分の手元の Windows PC で実行した結果です。当然のことながら、Apple Silicon の Mac 上では、プロセッサアーキテクチャをはじめ、異なる表示となります。
Blazor WebAsembly 上での実行結果
メンバー | 値 |
---|---|
OperatingSystem.IsBrowser() | True |
Framework Description | .NET 8.0.0 |
Process Architecture | Wasm |
OS Architecture | Wasm |
OS Description | Browser |
OS Platform | Other |
OS Version | 1.0.0.0 |
OS Version ServicePack |
何で判定できるか/何で判定するのがよいか
結論としては冒頭に書いたとおり、System.OperatingSystem
クラスの IsBrowser
静的メソッドを呼び出しての戻り値で判定すればよいでしょう。
とはいえ、念のため、他の情報源にも目を通しておきます。まずは、RuntimeInformation
クラスの OSDescription
が "Browser" であるか否かで判定できそうです。
いっぽうで、RuntimeInformation
クラスの ProcessArchitecture
や OSArchitecture
について、現状ですとブラウザ上での実行時のみ Wasm
になっています。しかしこのプロセッサアーキテクチャでの判定は止めた方がよいでしょう。というのも、今後将来、サーバー側でも WebAssembly に基づくプラットフォームで実行されるようになると (2023年12月現在では、ASP.NET Core はまだ公式には Wasmtime などのような WebAssembly プラットフォームでの実行はサポートされていない、と認識しています)、サーバー側での実行であっても、プロセッサアーキテクチャが "Wasm" になる可能性が高いと思われるからです。
はじめの結論に戻りますが、System.OperatingSystem
クラスの IsBrowser
静的メソッドにはもうひとつ、面白い特徴があります。IsBrowser
メソッドの実装は、なんと、即値なのです。例えば Blazor WebAssembly 用の System.Runtime.dll 中では、IsBrowser
メソッドは以下のコードとなっています。
public sealed class OperatingSystem ...
{
...
public static bool IsBrowser() => true;
...
実行時にあれこれ条件分岐して判断しているわけではないのですね。
まとめ
ある Razor コンポーネントの実装内で、実行時に、今現在このコンポーネントはサーバー側で実行されているのかブラウザ上で実行されているのかを、そう多くはないとは言え、判断したい場合がありえます。
そのような場合は、System.OperatingSystem
クラスの IsBrowser()
静的メソッドの戻り値を参照してください。その戻り値が true
であれば、ブラウザ上で実行されていると判断できます。
Learn, Practice, Share!