Xử lý ngoại lệ API ASP.NET Core Web


280

Tôi đang sử dụng ASP.NET Core cho dự án API REST mới của mình sau khi sử dụng API Web ASP.NET thông thường trong nhiều năm. Tôi không thấy bất kỳ cách nào tốt để xử lý các ngoại lệ trong API ASP.NET Web. Tôi đã cố gắng thực hiện bộ lọc / thuộc tính xử lý ngoại lệ:

public class ErrorHandlingFilter : ExceptionFilterAttribute
{
    public override void OnException(ExceptionContext context)
    {
        HandleExceptionAsync(context);
        context.ExceptionHandled = true;
    }

    private static void HandleExceptionAsync(ExceptionContext context)
    {
        var exception = context.Exception;

        if (exception is MyNotFoundException)
            SetExceptionResult(context, exception, HttpStatusCode.NotFound);
        else if (exception is MyUnauthorizedException)
            SetExceptionResult(context, exception, HttpStatusCode.Unauthorized);
        else if (exception is MyException)
            SetExceptionResult(context, exception, HttpStatusCode.BadRequest);
        else
            SetExceptionResult(context, exception, HttpStatusCode.InternalServerError);
    }

    private static void SetExceptionResult(
        ExceptionContext context, 
        Exception exception, 
        HttpStatusCode code)
    {
        context.Result = new JsonResult(new ApiResponse(exception))
        {
            StatusCode = (int)code
        };
    }
}

Và đây là đăng ký bộ lọc Khởi động của tôi:

services.AddMvc(options =>
{
    options.Filters.Add(new AuthorizationFilter());
    options.Filters.Add(new ErrorHandlingFilter());
});

Vấn đề tôi gặp phải là khi ngoại lệ xảy ra trong tôi AuthorizationFilterthì nó không được xử lý ErrorHandlingFilter. Tôi đã mong đợi nó sẽ được bắt ở đó giống như nó hoạt động với API Web ASP.NET cũ.

Vậy làm cách nào tôi có thể bắt tất cả các ngoại lệ của ứng dụng cũng như bất kỳ ngoại lệ nào từ Bộ lọc hành động?


3
Bạn đã thử UseExceptionHandlerphần mềm trung gian chưa?
Pawel

Tôi có một ví dụ ở đây về cách sử dụng UseExceptionHandlerphần mềm trung gian
Ilya Chernomordik

Câu trả lời:


537

Middleware xử lý ngoại lệ

Sau nhiều thử nghiệm với các phương pháp xử lý ngoại lệ khác nhau, cuối cùng tôi đã sử dụng phần mềm trung gian. Nó hoạt động tốt nhất cho ứng dụng ASP.NET Core Web API của tôi. Nó xử lý các trường hợp ngoại lệ của ứng dụng cũng như ngoại lệ từ các bộ lọc hành động và tôi có toàn quyền kiểm soát xử lý ngoại lệ và phản hồi HTTP. Đây là phần mềm trung gian xử lý ngoại lệ của tôi:

public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate next;
    public ErrorHandlingMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context /* other dependencies */)
    {
        try
        {
            await next(context);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(context, ex);
        }
    }

    private static Task HandleExceptionAsync(HttpContext context, Exception ex)
    {
        var code = HttpStatusCode.InternalServerError; // 500 if unexpected

        if      (ex is MyNotFoundException)     code = HttpStatusCode.NotFound;
        else if (ex is MyUnauthorizedException) code = HttpStatusCode.Unauthorized;
        else if (ex is MyException)             code = HttpStatusCode.BadRequest;

        var result = JsonConvert.SerializeObject(new { error = ex.Message });
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = (int)code;
        return context.Response.WriteAsync(result);
    }
}

Đăng ký nó trước khi MVC trong Startuplớp:

app.UseMiddleware(typeof(ErrorHandlingMiddleware));
app.UseMvc();

Bạn có thể thêm theo dõi ngăn xếp, tên loại ngoại lệ, mã lỗi hoặc bất cứ điều gì bạn muốn với nó. Rất linh hoạt. Đây là một ví dụ về phản ứng ngoại lệ:

{ "error": "Authentication token is not valid." }

Cân nhắc việc tiêm IOptions<MvcJsonOptions>vào Invokephương thức để sử dụng nó khi bạn tuần tự hóa đối tượng phản hồi để sử dụng các cài đặt tuần tự hóa của ASP.NET MVC JsonConvert.SerializeObject(errorObj, opts.Value.SerializerSettings)để có tính nhất quán tuần tự hóa tốt hơn trên tất cả các điểm cuối.

Cách tiếp cận 2

Có một API không rõ ràng khác được gọi là UseExceptionHandlerhoạt động "ok" cho phối cảnh đơn giản:

app.UseExceptionHandler(a => a.Run(async context =>
{
    var feature = context.Features.Get<IExceptionHandlerPathFeature>();
    var exception = feature.Error;

    var result = JsonConvert.SerializeObject(new { error = exception.Message });
    context.Response.ContentType = "application/json";
    await context.Response.WriteAsync(result);
}));

Đây không phải là một cách rất rõ ràng nhưng dễ dàng để thiết lập xử lý ngoại lệ. Tuy nhiên tôi vẫn thích cách tiếp cận phần mềm trung gian hơn nó vì tôi có nhiều quyền kiểm soát hơn với khả năng tiêm các phụ thuộc cần thiết.


4
Tôi đã đập đầu vào bàn làm việc để có một phần mềm trung gian tùy chỉnh hoạt động ngày hôm nay và nó hoạt động về cơ bản theo cách tương tự (tôi đang sử dụng nó để quản lý đơn vị công việc / giao dịch cho một yêu cầu). Vấn đề tôi gặp phải là các ngoại lệ được nêu ra trong 'tiếp theo' không bị bắt trong phần mềm trung gian. Như bạn có thể tưởng tượng, đây là vấn đề. Tôi đang làm gì sai / mất tích? Bất kỳ con trỏ hoặc đề nghị?
brappleye3

5
@ brappleye3 - Tôi đã tìm ra vấn đề là gì. Tôi vừa đăng ký phần mềm trung gian ở sai vị trí trong lớp Startup.cs. Tôi chuyển app.UseMiddleware<ErrorHandlingMiddleware>();đến chỉ trước đây app.UseStaticFiles();. Ngoại lệ dường như được bắt chính xác ngay bây giờ. Điều này khiến tôi tin rằng thực hiện app.UseDeveloperExceptionPage(); app.UseDatabaseErrorPage(); app.UseBrowserLink();một số hack phần mềm trung gian ma thuật nội bộ để có được thứ tự phần mềm trung gian ngay.
Jamadan

4
Tôi đồng ý rằng phần mềm trung gian tùy chỉnh có thể rất hữu ích nhưng sẽ đặt câu hỏi bằng cách sử dụng các ngoại lệ cho các tình huống NotFound, Un trái phép và BadRequest. Tại sao không chỉ đơn giản là đặt mã trạng thái (sử dụng NotFound (), v.v.) và sau đó xử lý nó trong phần mềm trung gian tùy chỉnh của bạn hoặc thông qua UseStatusCodePagesWithReExecute? Xem devtrends.co.uk/blog/handling-errors-in-asp.net-core-web-api để biết thêm
Paul Hiles

4
Thật tệ vì nó luôn được tuần tự hóa thành JSON, hoàn toàn bỏ qua việc đàm phán nội dung.
Konrad

5
@Konrad điểm hợp lệ. Đó là lý do tại sao tôi nói rằng ví dụ này là nơi bạn có thể bắt đầu, và không phải là kết quả cuối cùng. Đối với 99% API JSON là quá đủ. Nếu bạn cảm thấy câu trả lời này không đủ tốt, hãy thoải mái đóng góp.
Andrei

60

Mới nhất Asp.Net Core(ít nhất là từ 2.2, có thể sớm hơn) có phần mềm trung gian tích hợp giúp dễ dàng hơn một chút so với việc thực hiện trong câu trả lời được chấp nhận:

app.UseExceptionHandler(a => a.Run(async context =>
{
    var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>();
    var exception = exceptionHandlerPathFeature.Error;

    var result = JsonConvert.SerializeObject(new { error = exception.Message });
    context.Response.ContentType = "application/json";
    await context.Response.WriteAsync(result);
}));

Nó nên làm khá nhiều như nhau, chỉ cần một ít mã để viết.

Quan trọng: Hãy nhớ thêm nó trướcUseMvc (hoặc UseRoutingtrong .Net Core 3) vì thứ tự là quan trọng.


Liệu nó có hỗ trợ DI như một đối số cho trình xử lý hay người ta sẽ phải sử dụng mẫu định vị dịch vụ trong trình xử lý?
lp

31

Đặt cược tốt nhất của bạn là sử dụng phần mềm trung gian để đạt được đăng nhập mà bạn đang tìm kiếm. Bạn muốn đặt nhật ký ngoại lệ của mình vào một phần mềm trung gian và sau đó xử lý các trang lỗi của bạn được hiển thị cho người dùng trong một phần mềm trung gian khác. Điều đó cho phép tách logic và tuân theo thiết kế Microsoft đã đưa ra với 2 thành phần phần mềm trung gian. Đây là một liên kết tốt đến tài liệu của Microsoft: Xử lý lỗi trong Lõi ASP.Net

Ví dụ cụ thể của bạn, bạn có thể muốn sử dụng một trong các tiện ích mở rộng trong phần mềm trung gian StatusCodePage hoặc cuộn giống như của bạn này .

Bạn có thể tìm thấy một ví dụ ở đây để ghi lại các ngoại lệ: ExceptionHandlerMiddleware.cs

public void Configure(IApplicationBuilder app)
{
    // app.UseErrorPage(ErrorPageOptions.ShowAll);
    // app.UseStatusCodePages();
    // app.UseStatusCodePages(context => context.HttpContext.Response.SendAsync("Handler, status code: " + context.HttpContext.Response.StatusCode, "text/plain"));
    // app.UseStatusCodePages("text/plain", "Response, status code: {0}");
    // app.UseStatusCodePagesWithRedirects("~/errors/{0}");
    // app.UseStatusCodePagesWithRedirects("/base/errors/{0}");
    // app.UseStatusCodePages(builder => builder.UseWelcomePage());
    app.UseStatusCodePagesWithReExecute("/Errors/{0}");  // I use this version

    // Exception handling logging below
    app.UseExceptionHandler();
}

Nếu bạn không thích cách triển khai cụ thể đó, thì bạn cũng có thể sử dụng ELM Middleware và đây là một số ví dụ: Elm Exception Middleware

public void Configure(IApplicationBuilder app)
{
    app.UseStatusCodePagesWithReExecute("/Errors/{0}");
    // Exception handling logging below
    app.UseElmCapture();
    app.UseElmPage();
}

Nếu điều đó không phù hợp với nhu cầu của bạn, bạn luôn có thể cuộn thành phần Middleware của riêng mình bằng cách xem xét các triển khai ExceptionHandlerMiddleware và ElmMiddleware của họ để nắm bắt các khái niệm để xây dựng riêng của bạn.

Điều quan trọng là thêm phần mềm trung gian xử lý ngoại lệ bên dưới phần mềm trung gian StatusCodePages nhưng trên hết là các thành phần phần mềm trung gian khác của bạn. Bằng cách đó, phần mềm trung gian Exception của bạn sẽ nắm bắt ngoại lệ, ghi nhật ký, sau đó cho phép yêu cầu tiếp tục với phần mềm trung gian StatusCodePage sẽ hiển thị trang lỗi thân thiện với người dùng.


Không có gì. Tôi cũng đã cung cấp một liên kết đến một ví dụ để ghi đè UseStatusPages mặc định trong các trường hợp cạnh có thể đáp ứng tốt hơn yêu cầu của bạn.
Ashley Lee

1
Lưu ý rằng Elm không duy trì nhật ký và nên sử dụng Serilog hoặc NLog để cung cấp tuần tự hóa. Xem nhật ký ELM biến mất. Chúng ta có thể duy trì nó vào một tập tin hoặc DB không?
Michael Freidgeim

2
Liên kết bây giờ bị hỏng.
Mathias Lykkegaard Lorenzen

@AshleyLee, tôi nghi ngờ đó UseStatusCodePageslà việc sử dụng trong triển khai dịch vụ API Web. Không có lượt xem hay HTML nào cả, chỉ có phản hồi JSON ...
Paul Michalik

23

Câu trả lời được chấp nhận tốt đã giúp tôi rất nhiều nhưng tôi muốn vượt qua httpStatusCode trong phần mềm trung gian của mình để quản lý mã trạng thái lỗi khi chạy.

Theo liên kết này, tôi có một số ý tưởng để làm như vậy. Vì vậy, tôi đã hợp nhất câu trả lời Andrei với điều này. Vì vậy, mã cuối cùng của tôi là dưới đây:
1. Lớp cơ sở

public class ErrorDetails
{
    public int StatusCode { get; set; }
    public string Message { get; set; }

    public override string ToString()
    {
        return JsonConvert.SerializeObject(this);
    }
}

2. Loại lớp ngoại lệ tùy chỉnh

 public class HttpStatusCodeException : Exception
{
    public HttpStatusCode StatusCode { get; set; }
    public string ContentType { get; set; } = @"text/plain";

    public HttpStatusCodeException(HttpStatusCode statusCode)
    {
        this.StatusCode = statusCode;
    }

    public HttpStatusCodeException(HttpStatusCode statusCode, string message) : base(message)
    {
        this.StatusCode = statusCode;
    }

    public HttpStatusCodeException(HttpStatusCode statusCode, Exception inner) : this(statusCode, inner.ToString()) { }

    public HttpStatusCodeException(HttpStatusCode statusCode, JObject errorObject) : this(statusCode, errorObject.ToString())
    {
        this.ContentType = @"application/json";
    }

}


3. Middleware ngoại lệ tùy chỉnh

public class CustomExceptionMiddleware
    {
        private readonly RequestDelegate next;

    public CustomExceptionMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context /* other dependencies */)
    {
        try
        {
            await next(context);
        }
        catch (HttpStatusCodeException ex)
        {
            await HandleExceptionAsync(context, ex);
        }
        catch (Exception exceptionObj)
        {
            await HandleExceptionAsync(context, exceptionObj);
        }
    }

    private Task HandleExceptionAsync(HttpContext context, HttpStatusCodeException exception)
    {
        string result = null;
        context.Response.ContentType = "application/json";
        if (exception is HttpStatusCodeException)
        {
            result = new ErrorDetails() { Message = exception.Message, StatusCode = (int)exception.StatusCode }.ToString();
            context.Response.StatusCode = (int)exception.StatusCode;
        }
        else
        {
            result = new ErrorDetails() { Message = "Runtime Error", StatusCode = (int)HttpStatusCode.BadRequest }.ToString();
            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
        }
        return context.Response.WriteAsync(result);
    }

    private Task HandleExceptionAsync(HttpContext context, Exception exception)
    {
        string result = new ErrorDetails() { Message = exception.Message, StatusCode = (int)HttpStatusCode.InternalServerError }.ToString();
        context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
        return context.Response.WriteAsync(result);
    }
}


4. Phương pháp mở rộng

public static void ConfigureCustomExceptionMiddleware(this IApplicationBuilder app)
    {
        app.UseMiddleware<CustomExceptionMiddleware>();
    }

5. Cấu hình phương thức trong startup.cs

app.ConfigureCustomExceptionMiddleware();
app.UseMvc();

Bây giờ phương thức đăng nhập của tôi trong Trình điều khiển tài khoản:

 try
        {
            IRepository<UserMaster> obj = new Repository<UserMaster>(_objHeaderCapture, Constants.Tables.UserMaster);
            var Result = obj.Get().AsQueryable().Where(sb => sb.EmailId.ToLower() == objData.UserName.ToLower() && sb.Password == objData.Password.ToEncrypt() && sb.Status == (int)StatusType.Active).FirstOrDefault();
            if (Result != null)//User Found
                return Result;
            else// Not Found
                throw new HttpStatusCodeException(HttpStatusCode.NotFound, "Please check username or password");
        }
        catch (Exception ex)
        {
            throw ex;
        }

Ở trên, bạn có thể thấy nếu tôi không tìm thấy người dùng thì hãy nâng cao httpStatusCodeException, trong đó tôi đã vượt qua trạng thái httpStatusCode.NotFound và một thông báo tùy chỉnh
Trong phần mềm trung gian

bắt (ví dụ: httpStatusCodeException)

bị chặn sẽ được gọi sẽ vượt qua sự kiểm soát

nhiệm vụ riêng xử lýExceptionAsync (bối cảnh httpContext, ngoại lệ httpStatusCodeException)

.


Nhưng nếu tôi gặp lỗi thời gian chạy trước đây thì sao? Vì vậy, tôi đã sử dụng thử khối bắt, ném ngoại lệ và sẽ bị bắt trong khối bắt (Exception ngoại lệObj) và sẽ chuyển quyền kiểm soát tới

Nhiệm vụ Xử lý ngoại lệAsync (bối cảnh httpContext, ngoại lệ)

phương pháp.

Tôi đã sử dụng một lớp ErrorDetails để thống nhất.


Đặt phương pháp mở rộng ở đâu? Đáng tiếc là trong startup.cstrong void Configure(IapplicationBuilder app)tôi nhận được một lỗi IApplicationBuilder does not contain a definition for ConfigureCustomExceptionMiddleware. Và tôi đã thêm tài liệu tham khảo, ở đâu CustomExceptionMiddleware.cs.
Spedo De La Rossa

bạn không muốn sử dụng ngoại lệ vì chúng làm chậm apis của bạn. trường hợp ngoại lệ rất tốn kém.
lnaie

@Inaie, Không thể nói về điều đó ... nhưng có vẻ như bạn chưa bao giờ có ngoại lệ nào để xử lý .. Công việc tuyệt vời
Arjun

19

Để Định cấu hình hành vi xử lý ngoại lệ cho mỗi loại ngoại lệ, bạn có thể sử dụng Middleware từ các gói NuGet:

Mẫu mã:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddExceptionHandlingPolicies(options =>
    {
        options.For<InitializationException>().Rethrow();

        options.For<SomeTransientException>().Retry(ro => ro.MaxRetryCount = 2).NextPolicy();

        options.For<SomeBadRequestException>()
        .Response(e => 400)
            .Headers((h, e) => h["X-MyCustomHeader"] = e.Message)
            .WithBody((req,sw, exception) =>
                {
                    byte[] array = Encoding.UTF8.GetBytes(exception.ToString());
                    return sw.WriteAsync(array, 0, array.Length);
                })
        .NextPolicy();

        // Ensure that all exception types are handled by adding handler for generic exception at the end.
        options.For<Exception>()
        .Log(lo =>
            {
                lo.EventIdFactory = (c, e) => new EventId(123, "UnhandlerException");
                lo.Category = (context, exception) => "MyCategory";
            })
        .Response(null, ResponseAlreadyStartedBehaviour.GoToNextHandler)
            .ClearCacheHeaders()
            .WithObjectResult((r, e) => new { msg = e.Message, path = r.Path })
        .Handled();
    });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseExceptionHandlingPolicies();
    app.UseMvc();
}

16

Đầu tiên, cảm ơn Andrei vì tôi đã dựa vào giải pháp của mình dựa trên ví dụ của anh ấy.

Tôi bao gồm cả tôi vì đây là một mẫu hoàn chỉnh hơn và có thể giúp độc giả tiết kiệm thời gian.

Hạn chế của cách tiếp cận của Andrei là không xử lý ghi nhật ký, nắm bắt các biến yêu cầu có khả năng hữu ích và đàm phán nội dung (nó sẽ luôn trả về JSON bất kể khách hàng đã yêu cầu gì - XML ​​/ văn bản thuần túy, v.v.).

Cách tiếp cận của tôi là sử dụng ObjectResult cho phép chúng tôi sử dụng chức năng được đưa vào MVC.

Mã này cũng ngăn chặn bộ nhớ đệm của phản ứng.

Phản hồi lỗi đã được trang trí theo cách mà nó có thể được tuần tự hóa bởi trình tuần tự XML.

public class ExceptionHandlerMiddleware
{
    private readonly RequestDelegate next;
    private readonly IActionResultExecutor<ObjectResult> executor;
    private readonly ILogger logger;
    private static readonly ActionDescriptor EmptyActionDescriptor = new ActionDescriptor();

    public ExceptionHandlerMiddleware(RequestDelegate next, IActionResultExecutor<ObjectResult> executor, ILoggerFactory loggerFactory)
    {
        this.next = next;
        this.executor = executor;
        logger = loggerFactory.CreateLogger<ExceptionHandlerMiddleware>();
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await next(context);
        }
        catch (Exception ex)
        {
            logger.LogError(ex, $"An unhandled exception has occurred while executing the request. Url: {context.Request.GetDisplayUrl()}. Request Data: " + GetRequestData(context));

            if (context.Response.HasStarted)
            {
                throw;
            }

            var routeData = context.GetRouteData() ?? new RouteData();

            ClearCacheHeaders(context.Response);

            var actionContext = new ActionContext(context, routeData, EmptyActionDescriptor);

            var result = new ObjectResult(new ErrorResponse("Error processing request. Server error."))
            {
                StatusCode = (int) HttpStatusCode.InternalServerError,
            };

            await executor.ExecuteAsync(actionContext, result);
        }
    }

    private static string GetRequestData(HttpContext context)
    {
        var sb = new StringBuilder();

        if (context.Request.HasFormContentType && context.Request.Form.Any())
        {
            sb.Append("Form variables:");
            foreach (var x in context.Request.Form)
            {
                sb.AppendFormat("Key={0}, Value={1}<br/>", x.Key, x.Value);
            }
        }

        sb.AppendLine("Method: " + context.Request.Method);

        return sb.ToString();
    }

    private static void ClearCacheHeaders(HttpResponse response)
    {
        response.Headers[HeaderNames.CacheControl] = "no-cache";
        response.Headers[HeaderNames.Pragma] = "no-cache";
        response.Headers[HeaderNames.Expires] = "-1";
        response.Headers.Remove(HeaderNames.ETag);
    }

    [DataContract(Name= "ErrorResponse")]
    public class ErrorResponse
    {
        [DataMember(Name = "Message")]
        public string Message { get; set; }

        public ErrorResponse(string message)
        {
            Message = message;
        }
    }
}

9

Đầu tiên, cấu hình ASP.NET Core 2 Startupđể thực thi lại đến một trang lỗi cho bất kỳ lỗi nào từ máy chủ web và bất kỳ trường hợp ngoại lệ nào chưa được xử lý.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment()) {
        // Debug config here...
    } else {
        app.UseStatusCodePagesWithReExecute("/Error");
        app.UseExceptionHandler("/Error");
    }
    // More config...
}

Tiếp theo, xác định một loại ngoại lệ sẽ cho phép bạn ném lỗi với mã trạng thái HTTP.

public class HttpException : Exception
{
    public HttpException(HttpStatusCode statusCode) { StatusCode = statusCode; }
    public HttpStatusCode StatusCode { get; private set; }
}

Cuối cùng, trong bộ điều khiển của bạn cho trang lỗi, hãy tùy chỉnh phản hồi dựa trên lý do lỗi và liệu phản hồi sẽ được người dùng cuối nhìn thấy trực tiếp hay không. Mã này giả định tất cả các URL API bắt đầu bằng /api/.

[AllowAnonymous]
public IActionResult Error()
{
    // Gets the status code from the exception or web server.
    var statusCode = HttpContext.Features.Get<IExceptionHandlerFeature>()?.Error is HttpException httpEx ?
        httpEx.StatusCode : (HttpStatusCode)Response.StatusCode;

    // For API errors, responds with just the status code (no page).
    if (HttpContext.Features.Get<IHttpRequestFeature>().RawTarget.StartsWith("/api/", StringComparison.Ordinal))
        return StatusCode((int)statusCode);

    // Creates a view model for a user-friendly error page.
    string text = null;
    switch (statusCode) {
        case HttpStatusCode.NotFound: text = "Page not found."; break;
        // Add more as desired.
    }
    return View("Error", new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier, ErrorText = text });
}

ASP.NET Core sẽ ghi lại chi tiết lỗi để bạn gỡ lỗi, vì vậy mã trạng thái có thể là tất cả những gì bạn muốn cung cấp cho người yêu cầu (có khả năng không tin cậy). Nếu bạn muốn hiển thị thêm thông tin, bạn có thể nâng cao HttpExceptionđể cung cấp nó. Đối với lỗi API, bạn có thể đặt thông tin lỗi được mã hóa JSON trong phần thân thông báo bằng cách thay thế return StatusCode...bằng return Json....


0

sử dụng phần mềm trung gian hoặc IExceptionHandlerPathFeature là tốt. có một cách khác trong eshop

tạo một bộ lọc ngoại lệ và đăng ký nó

public class HttpGlobalExceptionFilter : IExceptionFilter
{
  public void OnException(ExceptionContext context)
  {...}
}
services.AddMvc(options =>
{
  options.Filters.Add(typeof(HttpGlobalExceptionFilter));
})
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.