C # WCF WebAPI Изменить HttpContent ответа - PullRequest
2 голосов
/ 11 июня 2011

Используя веб-API WCF, как мне изменить тело содержимого ответа после запуска логики приложения, но до его возвращения пользователю.Цель в том случае, если suppressstatuscontent имеет значение true, мы:

  • Добавить поле кода состояния в тело содержимого
  • Изменить код состояния в ответе на 200

Iпереопределили 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 ]

3 голосов
/ 11 июня 2011

Я не уверен в правильном подходе, но я бы попробовал что-то вроде этого:

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

0 голосов
/ 11 июня 2011

Вы можете анализировать содержимое как 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);
}
...