stackoverflow.com/questions/52049727/...

ичок в концепции промежуточного программного обеспечения и в настоящее время борюсь с правильным способом обработки исключений в моем проекте MVC Core.

Я хочу, чтобы исключение было перехвачено, зарегистрировано и затем отправлено пользователю на дружественную страницу с сообщением об ошибке. Сначала я пытался управлять всем этим в промежуточном программном обеспечении, но понял, что, вероятно, я делал это неправильно.

Поэтому, если я хочу, чтобы этот поток выполнялся, должен ли я использовать свое промежуточное программное обеспечение для регистрации исключений и app.UseExceptionHandler ("/ Error"), чтобы промежуточное программное обеспечение повторно выдало исключение на страницу? И если да, то как получить информацию об исключении на странице ошибок? И правильно ли, что механизм обработки исключений, который я хочу перехватить первым, должен быть последним в Configure?

Все примеры, которые я нашел, имеют дело исключительно с ошибками кода состояния HTTP, такими как 404; Я ищу для обработки фактических исключений (и их подклассы). Таким образом, на моих страницах просмотра я могу выдавать свои собственные исключения, где это применимо (например, если для представления предоставлено пустое значение для обязательного поля).

Фрагмент Startup.cs:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
                      ILoggerFactory loggerFactory, LoanDbContext context) {
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
   , loggerFactory.AddDebug();

    app.UseStatusCodePages();
    if (env.IsDevelopment() || env.IsEnvironment("qa")) {
        app.UseDeveloperExceptionPage();
        app.UseBrowserLink();
    } else {
        app.UseExceptionHandler("/Error");
    }
    app.UseMiddleware<MyExceptionHandler>(loggerFactory);
    // ... rest of Configure is irrelevant to this issue

MyExceptionHandler.cs

using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Data.SqlClient;
using System.Threading.Tasks;

namespace MyCompany.MyProject.Helpers
{
    /// <summary>
    /// A custom Exception Handler Middleware which can be re-used in other projects.
    /// </summary>
    public sealed class MyExceptionHandler
    {
        private readonly RequestDelegate _next;
        private readonly ILogger _logger;

        public MyExceptionHandler(RequestDelegate next, ILoggerFactory loggerFactory) {
            _next = next;
            _logger = loggerFactory.CreateLogger<MyExceptionHandler>();
        }

        public async Task Invoke(HttpContext context) {
            try {
                await _next(context);
            } catch (Exception ex) {
                HandleException(ex);
            }
        }

        // I realize this function looks pointless, but it will have more meat to it eventually.
        public void HandleException(Exception ex) {
            if (ex is ArgumentException argEx) {
                _logger.LogError(0, argEx, argEx.Message);
            } else if (ex is InvalidOperationException ioEx) {
                _logger.LogError(0, ioEx, "An Invalid Operation Exception occurred. This is usually caused by a database call that expects "
                    + "one result, but receives none or more than one.");
            } else if (ex is SqlException sqlEx) {
                _logger.LogError(0, sqlEx, $"A SQL database exception occurred. Error Number {sqlEx.Number}");
            } else if (ex is NullReferenceException nullEx) {
                _logger.LogError(0, nullEx, $"A Null Reference Exception occurred. Source: {nullEx.Source}.");
            } else if (ex is DbUpdateConcurrencyException dbEx) {
                _logger.LogError(0, dbEx, "A database error occurred while trying to update your item. This is usually due to someone else modifying the item since you loaded it.");
            } else {
                _logger.LogError(0, ex, "An unhandled exception has occurred.")
            }
        }
    }
}