C#WCF WebAPI修改响应的HttpContent

时间:2011-06-11 01:14:22

标签: c# xml wcf json wcf-web-api

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

一个主要问题是它无法处理两个xml和Json。我觉得必须有一个更好的方法解决这个问题,因为这感觉非常黑客。

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:0)

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

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

假设Parse将返回来自您可以修改的内容对象,而无需知道格式是什么。

这不是一个非常好的解决方案,但它将黑客的一点点封装起来。

更新:假设您可以从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);
}