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

Pat*_*ski 1 blazor blazor-client-side

在 Blazor WebAssembly 中,Console.WriteLine将日志写入 Javascript 控制台,并Console.Error.WriteLine写入错误。有没有办法在不使用 Javascript 的情况下编写警告或信息 - Blazor 相当于 Javascriptconsole.warnconsole.info

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

agu*_*ars 6

预览更新5

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

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

     protected override void OnInitialized()
     {
          _logger.LogWarning("warning");
          _logger.LogError("error");
     }
}
Run Code Online (Sandbox Code Playgroud)

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);
     }
}
Run Code Online (Sandbox Code Playgroud)

或者实现你的记录器:

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() { }
    }
}
Run Code Online (Sandbox Code Playgroud)

您的记录器提供商

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.
    }
}
Run Code Online (Sandbox Code Playgroud)

将其注入 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));
    });
Run Code Online (Sandbox Code Playgroud)

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

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

     protected override void OnInitialized()
     {
          _logger.LogWarning("warning");
          _logger.LogError("error");
     }
}
Run Code Online (Sandbox Code Playgroud)