2016-11-15 26 views
7

Tôi có ứng dụng lõi asp.net. Việc triển khai phương thức cấu hình chuyển hướng người dùng đến trang "Lỗi" khi có ngoại lệ (trong môi trường không phát triển)Xử lý ngoại lệ trong lõi asp.net?

Tuy nhiên, nó chỉ hoạt động nếu ngoại lệ xảy ra bên trong bộ điều khiển. Nếu ngoại lệ xảy ra bên ngoài bộ điều khiển, ví dụ trong phần mềm trung gian tùy chỉnh của tôi, thì người dùng sẽ không được chuyển hướng đến trang lỗi.

Làm cách nào để chuyển hướng người dùng đến trang "Lỗi" nếu có ngoại lệ trong phần mềm trung gian.

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

     app.UseApplicationInsightsRequestTelemetry(); 

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

     app.UseApplicationInsightsExceptionTelemetry(); 

     app.UseStaticFiles(); 
     app.UseSession(); 
     app.UseMyMiddleware(); 

     app.UseMvc(routes => 
     { 
      routes.MapRoute(
       name: "default", 
       template: "{controller=Home}/{action=Index}/{id?}"); 
     }); 
    } 

Cập nhật 1
tôi cập nhật mã trên với hai dòng sau đó bị mất tích trong bài viết ban đầu.

 app.UseSession(); 
     app.UseMyMiddleware(); 

Tôi cũng tìm thấy lý do tại sao app.UseExceptionHandler không thể chuyển hướng đến trang Lỗi.
Khi có một ngoại lệ trong mã phần mềm trung gian của tôi, app.UseExceptionHandler("\Home\Error") đang chuyển hướng đến \Home\Error như mong đợi; nhưng vì đó là một yêu cầu mới, phần mềm trung gian của tôi đã thực hiện lại và ném lại ngoại lệ.
Vì vậy, để giải quyết vấn đề tôi đã thay đổi phần mềm trung gian của tôi để chỉ thực hiện if context.Request.Path != "/Home/Error"

Tôi không chắc chắn đây có phải là cách chính xác để giải quyết vấn đề này hay không.

public class MyMiddleWare 
{ 
    private readonly RequestDelegate _next; 
    private readonly IDomainService _domainService; 

    public MyMiddleWare(RequestDelegate next, IDomainService domain) 
    { 
     _next = next; 
     _domainService = domain; 
    } 

    public async Task Invoke(HttpContext context) 
    { 
     if (context.Request.Path != "/Home/Error") 
     { 
      if (context.User.Identity.IsAuthenticated && !context.Session.HasKey(SessionKeys.USERINFO)) 
      {   
       // this method may throw exception if domain service is down 
       var userInfo = await _domainService.GetUserInformation(context.User.Name).ConfigureAwait(false);      

       context.Session.SetUserInfo(userInfo); 
      } 
     } 

     await _next(context); 
    } 
} 

public static class MyMiddleWareExtensions 
{ 
    public static IApplicationBuilder UseMyMiddleWare(this IApplicationBuilder builder) 
    { 
     return builder.UseMiddleware<MyMiddleWare>(); 
    } 
} 
+0

Trường hợp trong ví dụ là phần mềm trung gian tùy chỉnh của bạn ở đâu? Tôi nghĩ ** 'UseExeptionHandler' sẽ có thể xử lý nó, nhưng phần mềm trung gian của bạn cần được đăng ký ** sau ** **. – Tseng

Trả lời

5

Bạn nên viết phần mềm trung gian của riêng mình để xử lý xử lý ngoại lệ tùy chỉnh. Và chắc chắn rằng bạn thêm nó vào đầu (đầu tiên nếu có thể) của ngăn xếp middleware của bạn bởi vì các ngoại lệ xảy ra trong phần mềm trung gian "sớm hơn" trong ngăn xếp sẽ không được xử lý.

Ví dụ:

public class CustomExceptionMiddleware 
{ 
    private readonly RequestDelegate _next; 

    public CustomExceptionMiddleware(RequestDelegate next) 
    { 
     _next = next; 
    } 

    public async Task Invoke(HttpContext context) 
    { 
     try 
     { 
      await _next.Invoke(context); 
     } 
     catch (Exception e) 
     { 
      // Handle exception 
     } 
    } 
} 
+1

'Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware' thực hiện chính xác điều bạn đã gợi ý. Phần mềm trung gian này chuyển hướng đến trường hợp ngoại lệ được cung cấp. Bạn có thể xem mã https://github.com/aspnet/Diagnostics/blob/dev/src/Microsoft.AspNetCore.Diagnostics/ExceptionHandler/ExceptionHandlerMiddleware.cs – LP13

5

Bạn có thể sử dụng để xử lý các trường hợp ngoại lệ UseExceptionHandler(), đặt mã này trong bạn Startup.cs.

Sử dụngExceptionHandler có thể được sử dụng để xử lý ngoại lệ trên toàn cầu. Bạn có thể nhận được tất cả các chi tiết của đối tượng ngoại lệ như Stack Trace, ngoại lệ bên trong và những thứ khác. Và sau đó bạn có thể hiển thị chúng trên màn hình. Here

Tại đây bạn có thể đọc thêm về phần mềm trung gian chẩn đoán này và tìm cách sử dụng IExceptionFilter và bằng cách tạo trình xử lý ngoại lệ tùy chỉnh của riêng bạn.

app.UseExceptionHandler(
       options => 
       { 
        options.Run(
         async context => 
         { 
          context.Response.StatusCode = (int) HttpStatusCode.InternalServerError; 
          context.Response.ContentType = "text/html"; 
          var ex = context.Features.Get<IExceptionHandlerFeature>(); 
          if (ex != null) 
          { 
           var err = $"<h1>Error: {ex.Error.Message}</h1>{ex.Error.StackTrace}"; 
           await context.Response.WriteAsync(err).ConfigureAwait(false); 
          } 
         }); 
       } 
      ); 

Bạn có cũng để xóa mặc định thiết lập như UseDeveloperExceptionPage(), nếu bạn sử dụng nó, nó luôn luôn hiển thị trang báo lỗi mặc định.

if (env.IsDevelopment()) 
     { 
      //This line should be deleted 
      app.UseDeveloperExceptionPage(); 
      app.UseBrowserLink(); 
     } 
     else 
     { 
      app.UseExceptionHandler("/Home/Error"); 
     } 
+0

Tôi đã xem qua bài viết này trước đây. Tuy nhiên tôi nghĩ rằng vấn đề là bất cứ khi nào bạn thiết lập response.StatusCode đến 500 trình duyệt không hiển thị 'html' mà máy chủ gửi, thay vào đó trình duyệt hiển thị trang lỗi của riêng nó cho mã 500. Trong fiddler tôi thấy cơ thể phản hồi có thông báo lỗi rằng máy chủ gửi nhưng trình duyệt không hiển thị thông báo lỗi đó. – LP13

+0

Chỉ cần xóa khỏi ứng dụng startup.cs.UseDeveloperExceptionPage(); –

+0

btw tôi cũng đã tạo thuộc tính bộ lọc ngoại lệ tùy chỉnh bắt nguồn từ 'ExceptionFilterAttribute'. Điều này sẽ chăm sóc tất cả các ngoại lệ bên trong bộ điều khiển. Im tìm kiếm xử lý ngoại lệ trong phần mềm trung gian. Ngay cả khi tôi xử lý trên toàn cầu bằng cách sử dụng 'app.UseExceptionHandler' hoặc tạo phần mềm trung gian của riêng tôi để xử lý ngoại lệ, nó không chuyển hướng người dùng đến chế độ xem lỗi. – LP13