在Blazor WebAssembly中,Console.WriteLine
向Javascript控制台写入日志,Console.Error.WriteLine
写入错误。有没有任何方法可以在不使用Javascript的情况下编写警告或信息?Blazor与Javascriptconsole.warn
或console.info
的等价物是什么?
(一般来说,对于任何给定的函数调用,如何发现是否有Blazor替代Javascript interop?(
预览更新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 interop,Blazor似乎无法做到这一点。