2011-12-15 24 views
5

Tôi đã tạo một ứng dụng ASP.NET MVC 3, sử dụng httpErrors để xử lý việc hiển thị thông báo lỗi và tương tự cho người dùng. Mã đó hoạt động tốt và được sao chép bên dưới.Chuyển ngoại lệ sang trang lỗi tùy chỉnh bằng cách sử dụng IIS7 httpErrors

<httpErrors existingResponse="Replace" defaultResponseMode="ExecuteURL" errorMode="Custom"> 
    <clear/> 
    <error statusCode="403" path="/Error/Forbidden" responseMode="ExecuteURL"/> 
    <error statusCode="404" subStatusCode="-1" path="/Error/NotFound" responseMode="ExecuteURL"/> 
    <error statusCode="500" subStatusCode="-1" path="/Error/ServerError" responseMode="ExecuteURL"/> 
</httpErrors> 

Khi một ngoại lệ trong một bộ điều khiển xảy ra, BaseController.OnException được kích hoạt (BaseController là một lớp học sáng tạo của riêng tôi). Những gì tôi muốn làm trong chức năng đó là lưu trữ ngoại lệ để hành động ServerError của tôi có thể xem xét loại và thông điệp của nó để xác định những gì sẽ hiển thị cho người dùng. Toàn bộ phương thức được sao chép dưới đây.

protected override void OnException(ExceptionContext filterContext) 
{ 
    // doesn't work 
    this.TempData["exception"] = filterContext.Exception; 

    // doesn't work 
    this.Session["exception"] = filterContext.Exception; 

    // temporary hack 
    ErrorController.RequestExceptions[this.Request.UserHostAddress] = filterContext.Exception; 
    base.OnException(filterContext); 
} 

Khi yêu cầu đến tại ErrorController dụ (ErrorController là trong một không gian tên khác nhau, nhưng tôi không nghĩ đó là có liên quan), vì một lý do Server.GetLastError() trả về NULL, TempData là trống rỗng, phiên là trống rỗng, và Session.IsNewSession là đúng. Tôi đã cố gắng giải quyết vấn đề bằng cách lưu trữ một số loại ID yêu cầu, nhưng điều đó dường như không tồn tại, và ngay bây giờ giải pháp tốt nhất mà tôi có là cực kỳ hacky "lưu trữ nó bằng cách yêu cầu IP, sau đó xóa nó ngay sau khi ErrorController đã nhặt nó lên. "

Công việc này (đáng kinh ngạc), nhưng phải có giải pháp an toàn hơn và có khả năng mở rộng hơn. Tôi không chắc chắn tại sao TempData bị xóa hoặc tại sao Phiên được khởi động lại - có phải do lỗi hoặc tính này là hai yêu cầu riêng biệt không? Bất kể, có cách giải quyết nào để có được hành vi mong muốn không?

P.S. Tôi muốn, nếu có thể, sử dụng mục nhập httpErrors trong web.config chứ không phải là mã trong Application_Error: Nó có vẻ giống như một giải pháp rõ ràng hơn, nhiều khai báo hơn.

P.P.S. Tôi đã tìm thấy một bài viết về các vấn đề với đối tượng Session trong khi chuyển hướng (link) nhưng nó nói rằng vấn đề đã được sửa. Hầu hết những thứ khác tôi đã gặp phải là về hệ thống customErrors cũ hơn, nhưng tôi sẽ tiếp tục tìm kiếm.

+0

Bất kỳ tin tức về việc tại sao phiên sẽ bị xóa. Tôi có chính xác cùng một vấn đề. Xe tăng –

Trả lời

2

MVC được tích hợp sẵn để hỗ trợ xử lý Ngoại lệ và hiển thị chế độ xem tùy chỉnh. Theo mặc định, MVC thêm HandleErrorAttribute vào phương thức RegisterGlobalFilters trong tệp Global.asax.cs.

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     filters.Add(new HandleErrorAttribute()); 
    } 

Bạn cần thêm chế độ xem Được đặt tên là Error vào thư mục xem Shared. Quan điểm sẽ có một mô hình kiểu HandleErrorInfo mà như một tài sản mang tên Exception để có được ngoại lệ ném

@model System.Web.Mvc.HandleErrorInfo 

@Model.Exception.Message 
+0

Vì vậy, 'httpErrors' có gây nhầm lẫn, hoặc nó có nghĩa là để phục vụ một số mục đích khác mà tôi không hiểu? – ehdv

+0

@ehdv MVC thực hiện trên thời gian chạy Asp.Net. Nếu MVC ném một ngoại lệ (và bạn không xử lý nó trong MVC) nó sẽ được xử lý bởi thời gian chạy Asp.Net bằng cách sử dụng trình xử lý 'httpErrors' thích hợp. – Eranga

Các vấn đề liên quan