2013-03-04 38 views
16

Trong dự án ASP.NET MVC 4 Web API, tôi muốn thêm một tuỳ chỉnh HttpMessageHandler. Tôi đã thay đổi WebApiConfig lớp (trong \ App_Satrt \ WebApiConfig.cs), như sau:Cách triển khai HttpMessageHandler trong API Web?

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
     config.Routes.MapHttpRoute(
      name: "DefaultApi", 
      routeTemplate: "api/{controller}/{id}", 
      defaults: new { id = RouteParameter.Optional }, 
      constraints: null, 
      handler: new MyCustomizedHttpMessageHandler() 
     ); 
    } 
} 

Sau đó, tôi phát triển MyCustomizedHttpMessageHandler:

public class MyCustomizedHttpMessageHandler : HttpMessageHandler 
{ 
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     IPrincipal principal = new GenericPrincipal(
      new GenericIdentity("myuser"), new string[] { "myrole" }); 
     Thread.CurrentPrincipal = principal; 
     HttpContext.Current.User = principal; 

     return Task<HttpResponseMessage>.Factory.StartNew(() => request.CreateResponse()); 
    } 
} 

Tuy nhiên, yêu cầu đến API (giả sử http://mylocalhost.com/api/values) , luôn trả về mã trạng thái 200, không có bất kỳ dữ liệu nào. Tôi có nghĩa là nó không bao giờ được phương thức 'GET()' của ValuesController.cs.

Tôi đã bỏ lỡ điều gì? Làm cách nào để triển khai HttpMessageHandler đúng cách?

PS: Đã đọc tài liệu này: https://stackoverflow.com/a/12030785/538387, không giúp tôi.

Trả lời

22

Ở đây bạn đang tạo một HttpMessageHandler làm ngắn mạch yêu cầu và không cho phép yêu cầu chuyển qua phần còn lại của đường ống. Thay vào đó, bạn nên tạo một DelegatingHandler.

Ngoài ra còn có 2 loại đường dẫn xử lý tin nhắn trong API Web. Một là một đường ống thông thường, trong đó tất cả các yêu cầu cho tất cả các tuyến đường đi qua và một nơi khác có thể có trình xử lý tin nhắn cụ thể cho các tuyến đường nhất định.

  1. Cố gắng tạo ra một DelegatingHandler và thêm nó vào danh sách HttpConfiguration 's bạn xử lý tin nhắn:

    config.MessageHandlers.Add(new HandlerA()) 
    
  2. Nếu bạn muốn thêm một handler nhắn tuyến đường cụ thể, sau đó bạn có thể làm như sau :

    config.Routes.MapHttpRoute(
          name: "DefaultApi", 
          routeTemplate: "api/{controller}/{id}", 
          defaults: new { id = RouteParameter.Optional }, 
          constraints: null, 
          handler: 
            HttpClientFactory.CreatePipeline(
              new HttpControllerDispatcher(config), 
              new DelegatingHandler[]{new HandlerA()}) 
          ); 
    

This Web Api Poster cho thấy pipeli ne dòng chảy.

+0

Cảm ơn bạn. Giải pháp (1) hoạt động tốt. Nhưng số 2, 'new HttpControllerDispatcher()' nói: ** System.Web.Http.Dispatcher.HttpControllerDispatcher không chứa hàm tạo 0 tham số ** - Cập nhật: Tôi đã sửa mã của bạn. Cảm ơn bạn. – Tohid

+0

tôi đã cập nhật bài đăng trên của tôi too.thanks. –

+0

Ngoài ra, hãy thêm phần này của câu trả lời của Cường Lê vào câu trả lời của bạn: ** Để viết một trình xử lý tin nhắn tùy chỉnh, bạn nên lấy từ 'System.Net.Http.DelegatingHandler'. ** – Tohid

11

Để viết một handler thông báo tùy chỉnh, bạn nên xuất phát từ System.Net.Http.DelegatingHandler

class CustomMessageHandler : DelegatingHandler 
{ 
    protected override Task<HttpResponseMessage> 
     SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     IPrincipal principal = new GenericPrincipal(
      new GenericIdentity("myuser"), new string[] { "myrole" }); 
     Thread.CurrentPrincipal = principal; 
     HttpContext.Current.User = principal; 

     return base.SendAsync(request, cancellationToken); 
    } 
} 

Và gọi base.SendAsync để gửi yêu cầu để xử lý bên trong.

+2

@Cuonge Le - Cảm ơn bạn đã trả lời. Sau khi tôi thay thế 'CustomMessageHandler' bằng mã của bạn, nó sẽ gây ra lỗi trên' return base.SendAsync (request, cancelToken); 'nói: ** Trình xử lý bên trong chưa được gán. **. Những gì tôi bỏ lỡ một lần nữa? – Tohid

+0

@Counge Le - Sự kết hợp của câu trả lời của bạn và Kirran Chall, đã khắc phục được sự cố. Cám ơn bạn một lần nữa. – Tohid

+0

@Cuong Le tương đương với .NET 4.0 là gì? Tôi không thể tìm thấy DelegatingHandler cho .NET .4 ... làm thế nào có thể làm messagehandling trong 4.0. Cảm ơn bạn đã giúp đỡ. – jaxxbo

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