UseExceptionHandler Blazor на стороне сервера - PullRequest
1 голос
/ 30 января 2020

Может ли кто-нибудь подтвердить, что app.UseExceptionHandler() не работает для серверного блейзора?

Я видел несколько случаев, когда мой пользовательский 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.

Ответы [ 2 ]

1 голос
/ 14 апреля 2020

Действительно, большое количество ASP Core промежуточного программного обеспечения ios не будет работать полностью в серверном приложении Blazor. Это потому, что Blazor работает с SignalR и Blazor Hub.

Вы увидите, что при запуске приложения Blazor сначала появляются несколько HTTP-запросов, которые будут проходить конвейер до конца. (в большинстве случаев это начальная загрузка страницы, а затем фаза согласования). Но затем приходит запрос к «/ _blazor», и в этот момент соединение остается открытым для продолжения связи через веб-сокеты. Если после этого этапа у вас возникнет исключение, оно не войдет в ваш обработчик исключений.

Вы можете наблюдать это, создав небольшой класс промежуточного программного обеспечения, который зарегистрирован с помощью метода расширения UseMiddleware в IApplicationBuilder . Для такого промежуточного класса требуется метод 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

0 голосов
/ 04 мая 2020

Благодаря ответу @ 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.in Настроить использовать это промежуточное ПО в качестве первого промежуточного ПО:

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

примечание: Файл Error.razor на страницах должен иметь путь маршрута: @page "/error"

см. Вход в окно вывода в vs:

enter image description here

...