DelegatingHandler在WebApi中的响应

问题描述:

我目前正在使用几个代理处理程序(来自DelegatingHandler的类)在发送请求之前处理请求,例如验证签名等。这一切都非常好,因为我没有必须在所有呼叫上重复签名验证(例如)。DelegatingHandler在WebApi中的响应

我想对来自同一网页请求的响应使用相同的原则。是否有类似于DelegatingHandler的响应?以某种方式在返回方法之前捕获响应的方法?

其他信息: 我打电话使用HttpClient.PutAsync(...)

一个Web API是。你可以在延续任务中做到这一点。

我解释一下here

例如,此代码(来自上面的博客)跟踪请求URI并向响应添加虚拟标头。

public class DummyHandler : DelegatingHandler 
{ 
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     // work on the request 
     Trace.WriteLine(request.RequestUri.ToString()); 

     return base.SendAsync(request, cancellationToken) 
      .ContinueWith(task => 
      { 
       // work on the response 
       var response = task.Result; 
       response.Headers.Add("X-Dummy-Header", Guid.NewGuid().ToString()); 
       return response; 
      }); 
    } 
} 
+0

啊,现在我明白了使用ContinueWith的例子。这很好。谢谢(并且对于慢速回答感到抱歉) – Halvard 2012-08-21 11:20:06

+0

您会如何阅读此处的回复内容?我尝试阅读它,但它抛出一个对象处置异常。 – 2013-09-19 14:32:56

+0

@RossJones这是奇怪的...你可以发送repro? – Aliostad 2013-09-20 08:25:01

以下是拦截请求和响应的示例。重写的方法SendAsync用于捕获原始请求,而名为ResponseHandler的方法用于捕获响应。

实施例捕获原始请求和响应

using System.Net.Http; 
using System.Threading.Tasks; 
namespace webAPI_Test 
{ 
    public class MessageInterceptor : DelegatingHandler 
    { 
     protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) 
     { 
      // CATCH THE REQUEST BEFORE SENDING TO THE ROUTING HANDLER 
      var headers = request.ToString(); 
      var body = request.Content.ReadAsStringAsync().Result; 
      var fullRequest = headers + "\n" + body; 

      // SETUP A CALLBACK FOR CATCHING THE RESPONSE - AFTER ROUTING HANDLER, AND AFTER CONTROLLER ACTIVITY 
      return base.SendAsync(request, cancellationToken).ContinueWith(
         task => 
         { 
          // GET THE COPY OF THE TASK, AND PASS TO A CUSTOM ROUTINE 
          ResponseHandler(task); 

          // RETURN THE ORIGINAL RESULT 
          var response = task.Result; 
          return response; 
         } 
      ); 
     } 

     public void ResponseHandler(Task<HttpResponseMessage> task) 
     { 
      var headers = task.Result.ToString(); 
      var body = task.Result.Content.ReadAsStringAsync().Result; 

      var fullResponse = headers + "\n" + body; 
     } 
    } 
} 

要使用此方法,所述类需要被识别和注册为的MessageHandler。添加以下行到我的Global.asax文件...

示例如何注册新MessageInterceptor类

GlobalConfiguration.Configuration.MessageHandlers.Add(new MessageInterceptor()); 

这里是我的完整Global.asax文件。注意MessageInterceptor是如何引用...

Global.asax中的完整版显示MessageInterceptor整合

using System.Web.Http; 
using System.Web.Mvc; 
using System.Web.Optimization; 
using System.Web.Routing; 
namespace webAPI_Test 
{ 
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801 

    public class WebApiApplication : System.Web.HttpApplication 
    { 
     protected void Application_Start() 
     { 
      AreaRegistration.RegisterAllAreas(); 

      WebApiConfig.Register(GlobalConfiguration.Configuration); 
      FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
      RouteConfig.RegisterRoutes(RouteTable.Routes); 
      BundleConfig.RegisterBundles(BundleTable.Bundles); 

      GlobalConfiguration.Configuration.MessageHandlers.Add(new MessageInterceptor()); 
     } 
    } 
}