2012-04-23 9 views
11

Tôi sẽ bắt đầu với, vâng, chúng tôi đã tạo và đang sử dụng bộ lọc ngoại lệ kế thừa từ ExceptionFilterAttribute. Nó được đăng ký trong cấu hình khi khởi động ứng dụng ngay sau bộ lọc nhận dạng của chúng tôi và hoạt động khá nhiều như mong đợi nếu một lỗi xảy ra ở đâu đó bên trong API của chúng tôi.Xử lý ngoại lệ ASP.NET MVC Web API

Điều đó đang được nói, tôi đang tìm cách xử lý các lỗi xảy ra trước khi nó đạt đến API.

Lý do: Chúng tôi không bao giờ muốn trả lại lỗi YSOD và/hoặc lỗi HTML IIS. Chúng tôi LUÔN LUÔN muốn nhấn bộ lọc/bộ lọc ngoại lệ tùy chỉnh để chúng tôi có thể xử lý ghi nhật ký chính xác và trả về phản hồi JSON cho người dùng.

Ngay bây giờ, sử dụng Fiddler để thực hiện một yêu cầu, tôi có thể đính kèm vào quá trình w3wp.exe và xem yêu cầu nhấn phương thức Application_BeginRequest trong global.asax. Sau đó, nó chỉ trả về một câu trả lời 500. Nó không bao giờ phá vỡ trong mã với một ngoại lệ hoặc truy cập bất kỳ điểm break của tôi sau đó. Có vẻ như nó đang trả về lỗi IIS. Chúng tôi không bao giờ muốn điều này xảy ra. Chúng tôi cần khả năng nắm bắt tất cả các ngoại lệ "cấp thấp" này, ghi lại chúng và trả lại một cái gì đó có ý nghĩa cho người dùng.

Có điều gì đó chúng ta có thể làm để xử lý các lỗi trước đây, những gì có vẻ là nhấn mã ASP.NET MVC Web API?

+0

Điều này cảm thấy sai bằng cách nào đó. Bạn có ném ngoại lệ trong thư viện ở đâu đó không? Tại sao không chỉ bắt ngoại lệ trong bộ điều khiển và trả về chế độ xem lỗi do bạn chọn? –

+1

Điều này đang sử dụng API ASP.NET MVC Web, vì vậy chúng tôi không trả lại lượt xem từ bộ điều khiển. Chúng tôi trả về các phản hồi JSON/XML. Tôi cũng đề cập đến trong câu hỏi của tôi rằng tôi cần một cách để xử lý các ngoại lệ TRƯỚC KHI họ tiếp cận các bộ điều khiển. Ngay bây giờ chúng ta có một ExceptionFilter bắt các ngoại lệ ở bất cứ đâu khi chúng ta ở bên trong controller nên chúng ta không cần phải thử/nắm bắt trong mọi hành động. – phreak3eb

+0

Tôi không nghĩ rằng tôi hoàn toàn hiểu được câu hỏi của bạn. Loại lỗi nào bạn đang cố gắng nắm bắt chính xác? – cecilphillip

Trả lời

4

Mặc dù tôi thích câu trả lời của Darin nhưng nó không hoạt động trong trường hợp của chúng tôi vì khung ASP.NET MVC Web API chặn/xử lý ngoại lệ nội bộ và không tái ném để nhấn phương thức Application_Error trong Global.asax. Giải pháp của chúng tôi là điều này.

tôi đã kết thúc việc tạo ra một DelegatingHandler tùy chỉnh như sau:

public class PrincipalHandler : DelegatingHandler 
{ 
    protected const string PrincipalKey = "MS_UserPrincipal"; 
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     setAnonymousPrincipal(); 

     request = InitializeIdentity(request); 

     return base.SendAsync(request, cancellationToken) 
      .ContinueWith(r => 
           { 
            // inspect result for status code and handle accordingly 
            return r.Result; 
           }); 
    } 
} 

sau đó tôi đưa nó vào trong HttpConfiguration để chắc chắn rằng nó là xử lý đầu tiên/cuối cùng được nhấn. Trình xử lý theo cách hoạt động trong API Web theo kiểu phân cấp. Vì vậy, trình xử lý đầu tiên sẽ được truy cập theo yêu cầu, sẽ là trình xử lý cuối cùng được nhấn vào phản hồi. Ít nhất đây là sự hiểu biết của tôi, ai đó cảm thấy tự do để sửa tôi nếu tôi sai.

public static void ConfigureApis(HttpConfiguration config) 
{ 
    config.MessageHandlers.Insert(0, new PrincipalHandler()); 
} 

Bằng cách sử dụng phương pháp này, chúng tôi hiện có thể kiểm tra mọi kết quả quay lại trong bất kỳ phản hồi nào từ API web và bộ điều khiển. Điều này cho phép chúng tôi xử lý bất kỳ đăng nhập nào có thể cần phải xảy ra do kết quả của một thứ không được trả lại như chúng tôi mong đợi. Bây giờ chúng ta có thể thay đổi nội dung của phản hồi quay lại để IIS không chèn bất kỳ trang lỗi HTML mặc định nào nếu nó thấy một số mã trạng thái HTTP nhất định.

Vấn đề duy nhất tôi có với điều này và tôi hy vọng họ thay đổi nó trong bản phát hành API sắp tới, là họ không gửi ngoại lệ sao lưu trên Tác vụ được trả về từ base.SendAsync (). Vì vậy, thông tin duy nhất chúng tôi phải đi qua là mã trạng thái HTTP và cố gắng hết sức để đưa ra câu trả lời hợp lý hoặc có thể xảy ra cho người tiêu dùng.

+0

Đối với bất kỳ ai tìm kiếm tài liệu về kết nối cuộc gọi đến 'config.MessageHandlers.Insert()', nó có sẵn [trong tài liệu WebAPI] (http://www.asp.net/web-api/overview/working-with -http/http-message-handlers). –

+1

Nếu bạn muốn một trình xử lý lỗi toàn cục trong API Web có đầy đủ thông tin ngoại lệ, vui lòng bỏ phiếu cho tính năng này tại http://aspnetwebstack.codeplex.com/workitem/1001 –

+0

Điều này cũng giống như một biến thể tiện dụng: http: // blog.codeishard.net/2013/02/09/webapi-and-the-behavior-of-exceptions-and-an-alternative-configurable-way-to-deal/ – CrazyPyro