在 Blazor WebAssembly 中,如何编写警告或信息?

In Blazor WebAssembly, how to write a warning or an info?

在 Blazor WebAssembly 中,Console.WriteLine 将日志写入 Javascript 控制台,Console.Error.WriteLine 写入错误。有什么方法可以在不使用 Javascript 的情况下编写警告或信息——什么是 Blazor 等价于 Javascript console.warnconsole.info 的?

(一般来说,对于任何给定的函数调用,如何确定是否有 Blazor 替代 Javascript 互操作?)

更新预览5

默认记录器使用日志级别写入控制台,现在您无需创建记录器。

@using using Microsoft.Extensions.Logging
@inject ILogger<MyComponent> _logger
...
@code {

     protected override void OnInitialized()
     {
          _logger.LogWarning("warning");
          _logger.LogError("error");
     }
}

https://github.com/dotnet/aspnetcore/blob/b69457e606adf24f9bb76014bba3eea65c51b954/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyConsoleLogger.cs

预览前 5

您可以使用 JSInterop:

@inject IJSRuntime _jsRuntime
...
@code {

     protected override async Task OnInitializedAsync()
     {
          await _jsRuntime.InvokeVoidAsync("console.error", "ERROR").ConfigureAwait(false);
     }
}

或者实现你的记录器:

public class ConsoleLogger : ILogger
{
    private readonly IJSRuntime _jsRuntime;

    public ConsoleLogger(IJSRuntime jsRuntime)
    {
        _jsRuntime = jsRuntime ?? throw new ArgumentNullException(nameof(jsRuntime));
    }

    public IDisposable BeginScope<TState>(TState state)
    {
        return NoOpDisposable.Instance;
    }

    public bool IsEnabled(LogLevel logLevel)
    {
        return logLevel >= LogLevel.Warning;
    }

    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
    {
        var formattedMessage = formatter(state, exception);
        switch(logLevel)
        {
            case LogLevel.Critical:
            case LogLevel.Error:
                _jsRuntime.InvokeVoidAsync("console.error", formattedMessage);
                break;
            case LogLevel.Warning:
                _jsRuntime.InvokeVoidAsync("console.warn", formattedMessage);
                break;
            case LogLevel.Information:
                _jsRuntime.InvokeVoidAsync("console.info", formattedMessage);
                break;
            case LogLevel.Trace:
            case LogLevel.Debug:
                _jsRuntime.InvokeVoidAsync("console.debug", formattedMessage);
                break;
            default:
                _jsRuntime.InvokeVoidAsync("console.log", formattedMessage);
                break;
        }
    }

    [SuppressMessage("Major Code Smell", "S3881:\"IDisposable\" should be implemented correctly", Justification = "From default console logger")]
    [SuppressMessage("Critical Code Smell", "S2223:Non-constant static fields should not be visible", Justification = "From default console logger")]
    [SuppressMessage("Critical Code Smell", "S1186:Methods should not be empty", Justification = "From default console logger")]
    private class NoOpDisposable : IDisposable
    {            
        public static NoOpDisposable Instance = new NoOpDisposable();
            
        public void Dispose() { }
    }
}

您的记录器提供商

public class ConsoleLoggerProvider : ILoggerProvider
{
    private readonly IServiceCollection _services;
    ILogger _logger;
    public ConsoleLoggerProvider(IServiceCollection services)
    {
        _services = services ?? throw new ArgumentNullException(nameof(services));
    }

    public ILogger CreateLogger(string categoryName)
    {
        if (_logger != null)
        {
            return _logger;
        }

        using var provider = _services.BuildServiceProvider();
        var jsRuntime = provider.GetRequiredService<IJSRuntime>();
        _logger = new ConsoleLogger(jsRuntime);
        return _logger;
    }

    public void Dispose()
    {
        // nothing to dispose.
    }
}

注入DI:

public static async Task Main(string[] args)
{
    var builder = WebAssemblyHostBuilder.CreateDefault(args);            
    builder.RootComponents.Add<App>("app");
    builder.Services.AddLogging(options =>
    {
        options.ClearProviders();
        options.AddProvider(new ConsoleLoggerProvider(options.Services));
    });

在您的组件或服务中注入 ILogger<T> 并使用此记录器以警告或错误级别登录控制台

@using using Microsoft.Extensions.Logging
@inject ILogger<MyComponent> _logger
...
@code {

     protected override void OnInitialized()
     {
          _logger.LogWarning("warning");
          _logger.LogError("error");
     }
}

从 3.2.0-preview4 开始,如果没有 Javascript 互操作,似乎无法在 Blazor 中执行此操作。