更改 WCF Web Api HttpContext 响应

Posted

技术标签:

【中文标题】更改 WCF Web Api HttpContext 响应【英文标题】:Change WCF WebApi HttpContent response 【发布时间】:2011-09-12 21:30:59 【问题描述】:

使用 WCF Web API 在应用程序逻辑运行后但在返回给用户之前,我将如何更改响应的内容主体。目标是如果 suppressstatuscontent 为真,我们:

向内容正文添加状态码字段 将响应中的状态码更改为 200

我已经覆盖了一个 DelegatingChannel 并且在 SendAsnyc 中有一些看起来像这样的代码:

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)

   return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>(task =>
   
      var response = task.Result;

      if (CheckIfRequestHadSuppressStatusCode(request) == true)
      
         string newResponse = (response.Content == null) ? "" : response.Content.ReadAsString();
         newResponse = "<body>" +newResponse + "</body><statuscode>" + response.StatusCode + "</statuscode>";
         response.StatusCode = HttpStatusCode.OK;                                 
      
      return response;
   );

一个主要问题是这个不能同时处理xmlJson。我觉得必须有更好的方法来解决这个问题,因为这感觉很hacky。

【问题讨论】:

【参考方案1】:

我不确定正确的方法,但我会尝试这样的方法:

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)

   return base.SendAsync(request, cancellationToken)
      .ContinueWith<HttpResponseMessage>(task =>
      
         var response = task.Result;
         if (CheckIfRequestHadSuppressStatusCode(request) == true)
         
            switch(response.Content.Headers.ContentType.MediaType)
            
               case "application/xml":
                  response.Content = new XmlWithStatusContent(response.Content)
                  break;
               case "application/json":
                  response.Content = new JsonWithStatusContent(response.Content)
                  break;
            

            response.StatusCode = HttpStatusCode.OK;                                 
         
         
         return response;
      );

您可以将添加额外状态代码标记的代码封装在专用版本的 HttpContent(例如 XmlWithStatusContent 和 JsonWithStatusContent)中。

【讨论】:

【参考方案2】:

您可以将内容解析为 XML 或 JSON(您可以将该功能封装在它自己的类中),然后您可以添加独立于格式的字段(独立于 SendAsync 不不需要知道)。

var newResponse = ContentDecoder.Parse(response.Content).AddField("statuscode", response.StatusCode).ToString();

假设Parse 会返回一种内容对象,您可以修改而无需知道格式是什么。

这不是一个真正好的解决方案,但它稍微封装了一些hackiness。

更新:假设您可以从HttpResponseMessage 获取并完全控制生成响应,那么您可以有专门的子类来处理它:

interface IHttpResponseContent

    void AddField(string name, string value);


class XmlHttpResponseMessage : HttpResponseMessage, IHttpResponseContent


在生成响应时,您改为创建 Xml/JsonHttpResponseMessage 对象。然后你可以这样做:

var newResponse = response as IHttpResponseContent;
if (newResponse != null)

    newResponse.AddField("statuscode", response.StatusCode);

【讨论】:

以上是关于更改 WCF Web Api HttpContext 响应的主要内容,如果未能解决你的问题,请参考以下文章

将 WCF 转换为 WEB API:在 WEB API 中使用包装器重用 WCF 服务是个好主意吗?

WCF Web API WCF REST 和 Web Service 的区别

ASP.Net Web API 与 WCF - Web API 能否用于向单例 WCF 服务提供基于 REST 的通信?

WCF、Web API、WCF REST 和 Web 服务之间的区别?

web service, wcf, wcf rest, web api之间的区别

Web Service vs WCF vs WCF REST vs Web API