繁体   English   中英

UseExceptionHandler Blazor 服务器端

[英]UseExceptionHandler Blazor server-side

有人可以确认app.UseExceptionHandler()不适用于服务器端 blazor 吗?

我见过几种情况,其中我的自定义ErrorHandler没有捕获我的应用程序抛出的异常。 示例代码

Startup.cs

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider)
{
    ...
    app.UseExceptionHandler(new ExceptionHandlerOptions { ExceptionHandler = ErrorHandler.HandleError });
    ...
}

ErrorHandler.cs

public static async Task HandleError(HttpContext context)
{
    var error = context.Features.Get<IExceptionHandlerFeature>()?.Error;
    var message = error?.Message ?? "[EXCEPTION NOT FOUND]";        
    return;
}

一个例子是当我的存储库抛出异常时: The instance of entity type cannot be tracked because another instance with the same key value for {'Id'} is already being tracked

我的 MVC 解决方案正在捕获所有异常,并且它使用了类似的 ErrorHandling 实现。

事实上,许多 ASP Core 中间件方案在服务器端 Blazor 应用程序中无法完全运行。 这是因为 Blazor 与 SignalR 和 Blazor Hub 一起使用。

您将看到,在启动 Blazor 应用程序时,首先有几个 HTTP 请求将通过管道直到结束。 (在大多数情况下,这些是初始页面加载,然后是协商阶段)。 但是随后会向“/_blazor”发出请求,此时连接保持打开状态以继续通过 websockets 进行通信。 如果您在此阶段之后出现异常,它不会进入您的异常处理程序。

您可以通过创建一个小的中间件类来观察这一点,该类通过IApplicationBuilder上的UseMiddleware扩展方法注册 这样的中间件类需要一个像这样的Invoke方法,例如:

.....
public class TestMiddleware
{
    private readonly RequestDelegate _next;
    public TestMiddleware(RequestDelegate next)
    {
       _next = next
    }

    public async Task Invoke(HttpContext context)
    {
       await _next(context);
    }
....

如果您在Invoke 中放置一个断点,您会注意到一旦上下文参数用于路径 "/_blazor" ,您将不会再进一步​​。

这是另一个讨论类似问题的链接,不同于异常处理程序,但也与 ASP.NET 中间件有关: https : //github.com/aspnet/SignalR/issues/1334

感谢@reno 的回答,我刚刚完成了他的回答

只需 3 个步骤:

1.创建一个异常中间件:

 public class ExceptionMiddleware
{
    public readonly RequestDelegate _next;
    string _path;
    private readonly ILogger<ExceptionMiddleware> _logger;

    public ExceptionMiddleware(ILogger<ExceptionMiddleware> logger, RequestDelegate next,string Path)
    {
        _next = next;
        _path = Path;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (System.Exception ex)
        {
            _logger.LogError(ex,$"RequsetPath: {context.Request.Path}",default);
            context.Response.Redirect(_path);

        }
    }

}

2.创建一个自定义的 MiddlewareExtension:

public static class MiddlewareExtensions
{
    public static IApplicationBuilder UsemycustomException(
        this IApplicationBuilder builder,string path)
    {
        return builder.UseMiddleware<ExceptionMiddleware>(path);
    }
}

3.在配置中使用这个中间件作为第一个中间件:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
  app.UsemycustomException("/Error");
  .
  .
  .
}

注意:Pages 中的Error.razor文件必须有路由路径: @page "/error"

请参阅输出窗口登录 vs:

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM