WebApi 中响应的 DelegatingHandler

Posted

技术标签:

【中文标题】WebApi 中响应的 DelegatingHandler【英文标题】:DelegatingHandler for response in WebApi 【发布时间】:2012-08-15 13:39:43 【问题描述】:

我目前正在使用多个委托处理程序(派生自 DelegatingHandler 的类)在请求发送之前对其进行处理,例如验证签名等。这一切都非常好,因为我不必复制所有调用的签名验证(例如)。

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

附加信息: 我正在使用 HttpClient.PutAsync(...) 调用 Web api

【问题讨论】:

你可以通过另一个 DelegatingHandler 来完成你的任务。见docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/… 【参考方案1】:

是的。您可以在后续任务中执行此操作。

我解释一下here。

例如,这段代码(来自上面的博客)跟踪请求 URI 并在响应中添加一个虚拟标头。

public class DummyHandler : DelegatingHandler

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    
        // work on the request 
       Trace.WriteLine(request.RequestUri.ToString());

       var response = await base.SendAsync(request, cancellationToken);
       response.Headers.Add("X-Dummy-Header", Guid.NewGuid().ToString());
       return response;
    

【讨论】:

有一个更简单的方法:你可以用async关键字标记“SendAsync”,然后执行await base.SendAsync(...)作为第一条语句。后面的一切都对应一个响应处理。【参考方案2】:

这是一个拦截请求和响应的示例。重写的方法 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 是如何被引用的...

显示 MessageInterceptor 集成的 Global.asax 完整版

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());
        
    

【讨论】:

以上是关于WebApi 中响应的 DelegatingHandler的主要内容,如果未能解决你的问题,请参考以下文章

WebAPI:HttpClient 响应字符串模型绑定

WebApi - 如何响应 Flash 文件并在浏览器中显示

OData v4 WebAPI 响应中的项目计数

格式化 webapi 响应 .net 核心

如何在 Ocelot 和 .Net WebApi 中覆盖 AuthorizationMiddleware 时返回未经授权的响应

webapi响应时怎么获取header c