頑張らないために頑張る

ゆるく頑張ります

Blazor Serverでデータをブラウザコンソールに出力する方法

Posted at — Dec 10, 2025

概要

Blazor Serverアプリケーションを開発していると、デバッグのためにブラウザのコンソールにデータを出力したくなることよくがあります。まぁ「デバッガー使えばいいじゃん」はたしかにそうなのですが、単純に「ここの処理通過してるか見ておきたいなー」程度の確認のとき、パッと「********hoge処理通過********」とか適当な文字列をコンソールに出したりします。

しかし、ことBlazorでの開発の場合、コンソールに出力するSystem.Diagnostics.Debug.WriteLine()Console.WriteLine()を使っても、ブラウザのコンソールには表示されません。今回はこの点について書きたいと思います。

なぜ表示されないのか

結論から言えば、Blazor Serverの仕組みに起因しています。

Blazor Serverでは、C#のコードはサーバー側で実行されます。

上記のようにそれぞれ「サーバー側」で実行され出力されます。しかし、ブラウザはクライアント側で動作しているため、サーバー側のコンソール出力は見えないのです。考えれば当たり前体操なのですが、つい忘れがち。

解決方法: JSInteropを使う

出力されているところはわかったのですが、「確認したいんだよぉ、ブラウザのコンソールでよぉ!」を実現するにはまあまあ面倒です。というのも、ブラウザのコンソールに出力するにはJavaScript Interop (JSInterop) を使って、JavaScriptのconsole.log()を呼び出す必要があります。

方法1: IJSRuntimeを直接使用する

最もシンプルな方法は、IJSRuntimeを使ってJavaScriptのconsole.logを直接呼び出すことです。

@page "/console-example"
@inject IJSRuntime JS

<h3>ブラウザコンソール出力のデモ</h3>

<button @onclick="LogToConsole">ブラウザコンソールに出力</button>

@code {
    private async Task LogToConsole()
    {
        await JS.InvokeVoidAsync("console.log", "Hello from Blazor Server!");
    }
}

この方法には以下のようなメリットがあります。

方法2: 複数の値やオブジェクトを出力する

@code {
    private async Task LogMultipleValues()
    {
        var user = new { Name = "田中太郎", Age = 30 };
        await JS.InvokeVoidAsync("console.log", "ユーザー情報:", user);
    }
}

方法3: ヘルパーメソッドを作成する

頻繁に使用する場合は、ヘルパークラスを作成すると便利です。

// Services/ConsoleLogger.cs
public class ConsoleLogger
{
    private readonly IJSRuntime _js;

    public ConsoleLogger(IJSRuntime js)
    {
        _js = js;
    }

    public async Task Log(params object[] args)
    {
        await _js.InvokeVoidAsync("console.log", args);
    }

    public async Task Warn(params object[] args)
    {
        await _js.InvokeVoidAsync("console.warn", args);
    }

    public async Task Error(params object[] args)
    {
        await _js.InvokeVoidAsync("console.error", args);
    }
}

Program.csに登録

builder.Services.AddScoped<ConsoleLogger>();

使用例

@page "/logger-example"
@inject ConsoleLogger Logger

<button @onclick="TestLogger">各種ログ出力</button>

@code {
    private async Task TestLogger()
    {
        await Logger.Log("通常のログ");
        await Logger.Warn("警告メッセージ");
        await Logger.Error("エラーメッセージ");
    }
}

方法4: カスタムJavaScript関数を作成する

より高度な出力を行いたい場合は、カスタムJavaScript関数を作成できます。でも今回の「ちょっと確認したい」みたいな場合には重すぎるんですよねぇ・・・。

wwwroot/js/consoleHelper.js

window.consoleHelper = {
    logWithTimestamp: function(message) {
        const timestamp = new Date().toLocaleTimeString();
        console.log(`[${timestamp}] ${message}`);
    },
    logObject: function(obj) {
        console.log(JSON.stringify(obj, null, 2));
    }
};

Pages/_Host.cshtmlまたはApp.razorで読み込み

<script src="js/consoleHelper.js"></script>

使用例

@code {
    private async Task LogWithCustomFunction()
    {
        await JS.InvokeVoidAsync("consoleHelper.logWithTimestamp", 
            "カスタム関数からの出力");
    }
}

注意点

非同期処理が必要

JSInteropは非同期処理なので、awaitasyncを使用する必要があります。

レンダリング前に呼び出せない

コンポーネントの初期化中(OnInitializedなど)で呼び出す場合は、OnAfterRenderAsyncを使用してください。

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        await JS.InvokeVoidAsync("console.log", "コンポーネントがレンダリングされました");
    }
}

プリレンダリングに注意

Blazor Serverではデフォルトでプリレンダリングが有効になっており、サーバー側で最初のレンダリングが行われます。ただ、この時点ではJSInteropは使用できません。

プリレンダリングを無効にする場合は、_Host.cshtmlで以下のように設定します。

<component type="typeof(App)" render-mode="Server" />

まとめ

Blazor Serverでブラウザコンソールに出力するには、以下のようなわりと面倒な手順をどれかしら採用する必要があります。

  1. IJSRuntimeを使用してconsole.logを呼び出す
  2. ヘルパークラスを作成して再利用性を高める
  3. カスタムJavaScript関数で拡張機能を実装する

BlazorだとReactやVue.jsとは感覚が異なるので、割と沼だと思ってます。

参考

comments powered by Disqus