3

使用 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;
   });

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

4

2 回答 2

4

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

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)中。

于 2011-06-11T01:58:27.460 回答
0

您可以将内容解析为 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);
}
于 2011-06-11T01:39:10.813 回答