обработка исключения в ASP. NET 3.1 базовом контроллере при использовании бритвенных страниц - PullRequest
3 голосов
/ 26 апреля 2020

У меня есть ASP. NET Веб-сайт Core 3.1, который использует бритвенные страницы, но также имеет один контроллер, который наследуется от ASP. NET Класс Core Controller. Контроллер обрабатывает полезную нагрузку и затем перенаправляет на одну из бритвенных страниц в случае успеха. Я замечаю, что когда в контроллере есть необработанное исключение, браузер отображает HTTP 400 - ошибка неверного запроса, но я хочу, чтобы контроллер просто использовал обработчик исключений, который я уже определил, и выглядит так:

if (env.IsDevelopment())
   app.UseDeveloperExceptionPage();
else
   app.UseExceptionHandler("/Error");

В приведенном выше пути "/ Ошибка" - это страница бритвы. В режиме без разработки контроллер не использует мой обработчик исключений и просто отображает HTTP 400 - ошибка браузера Bad Request.

Мне удалось заставить его работать с классом фильтра исключений, где внутри метода OnException () я зарегистрировать ошибку и вручную перенаправить на страницу «/ Ошибка». Фильтр исключений выглядит следующим образом:

private class CustomExceptionFilter : IExceptionFilter
{
    private readonly IWebHostEnvironment hostingEnvironment;

    private readonly ILogger<CustomExceptionFilter> logger;

    public CustomExceptionFilter(IWebHostEnvironment hostingEnvironment, ILogger<CustomExceptionFilter> logger)
    {
        this.hostingEnvironment = hostingEnvironment;
        this.logger = logger;
    }

    public void OnException(ExceptionContext context)
    {
        if (this.hostingEnvironment.IsDevelopment())
        {
            return;
        }

        this.logger.LogError(context.Exception, string.Empty);
        context.Result = new RedirectToPageResult("/Error");
    }

Затем я определил [TypeFilter (typeof (CustomExceptionFilter)))] на самом контроллере. Кажется, все работает, но кажется, что движущихся частей много. Это единственный способ сделать это или, может быть, я что-то упускаю?

Вот код запуска:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseForwardedHeaders();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");

        app.UseHsts(options => options.MaxAge(365).IncludeSubdomains());
    }

    app.UseStaticFiles();

    app.UseCookiePolicy();

    app.UseXRobotsTag(options => options.NoIndex().NoFollow());

    app.UseXfo(options => options.SameOrigin());

    app.UseXXssProtection(options => options.EnabledWithBlockMode());

    app.UseXContentTypeOptions();

    app.UseNoCacheHttpHeaders();

    app.UseRedirectValidation();

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapRazorPages();
    });
}

Заранее спасибо!

Ответы [ 3 ]

0 голосов
/ 26 апреля 2020

Если вы хотите go с app.UseExceptionHandler("/Error");, тогда ваша страница бритвы может выглядеть примерно так:

Error.cs html

@page "/Error"
@model Pages.Error

@{
  Layout = null;
}

<h1>An unexpected error occured. Status Code: @HttpContext.Response.StatusCode</h1>

Error.cs html .cs

public class Error : PageModel
  {
    private readonly ILogger<Error> _logger;

    public Error(ILogger<Error> logger)
    {
      _logger = logger;
    }

    public void OnGet()
    {
      var exceptionHandlerFeature = HttpContext.Features.Get<IExceptionHandlerFeature>();
      if(exceptionHandlerFeature?.Error != null)
        _logger.LogError($"This is a message from logger: {exceptionHandlerFeature.Error.Message}");
    }
  }
0 голосов
/ 26 апреля 2020

Я наконец понял, что случилось. Мой контроллер обрабатывал метод POST. При возникновении любых необработанных исключений код пытается запустить мой обработчик исключений. Из-за POST он будет публиковаться на моей странице обработчика исключений, но это не получится из-за отсутствия токена проверки запроса AntiForgery, поэтому он выдаст HTTP 400 - Bad Request, который я видел ранее на своих страницах, использующих jQuery с AJAX если токен отсутствует. В общем, чтобы решить эту проблему, я собираюсь добавить атрибут [IgnoreAntiforgeryToken] в мой обработчик страниц с ошибками бритвы.

0 голосов
/ 26 апреля 2020

Попробуйте это приложение.UseExceptionHandler ("/ Home / Error"); Причина работы, пожалуйста, проверьте ваш HomeController. По умолчанию должен быть выбран метод действия [ResponseCache (Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] publi c IActionResult Error () {return View (new ErrorViewModel {RequestId = Activity) .Current? .Id ?? HttpContext.TraceIdentifier}); }

Если его нет, вы можете создать этот метод в любом из ваших контроллеров и указать путь к нему, например, app.UseExceptionHandler ("/ YourController / Error");

...