C# WCF WebAPI Modify Response's HttpContent

徘徊边缘 提交于 2019-12-11 02:15:57

问题


Using the WCF Web API how would I go about changing a response's content body after the application logic has been run but before it's returned to the user. The goal is if suppressstatuscontent is true we:

  • Add a statuscode field to the content body
  • Change the statuscode on the response to 200

I have overridden a DelegatingChannel and in the SendAsnyc have some code that looks like this:

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

A major problem is this doesn't handle BOTH xml and Json. I feel like there must be a much better way to go about the problem as this feels very hacky.


回答1:


I'm not sure of the right approach but I would try something like this,

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

You can encapsulate the code that adds the extra status code markup in specialized versions of HttpContent (e.g. XmlWithStatusContent and JsonWithStatusContent).




回答2:


You could parse the content as either XML or JSON (you can encapsulate that functionality in it's own class) which then gives you the ability to add the field independent of the format (independent in the sense that the SendAsync doesn't need to know).

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

assuming Parse would return come kind of content object you can modify without having to know what the format is.

It's not a really a nice solution but it encapsulates the hackiness away a bit.

Update: Assuming you can dereive from HttpResponseMessage and are in full control of generating the response then you could have specialised subclasses dealing with it:

interface IHttpResponseContent
{
    void AddField(string name, string value);
}

class XmlHttpResponseMessage : HttpResponseMessage, IHttpResponseContent
{
}

When generating the response you create Xml/JsonHttpResponseMessage objects instead. Then you can do:

var newResponse = response as IHttpResponseContent;
if (newResponse != null)
{
    newResponse.AddField("statuscode", response.StatusCode);
}


来源:https://stackoverflow.com/questions/6313461/c-sharp-wcf-webapi-modify-responses-httpcontent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!