3

WCF Web API を使用して、アプリケーション ロジックが実行された後、ユーザーに返される前に、応答のコンテンツ本文を変更するにはどうすればよいでしょうか。目標は、suppressstatuscontent が true の場合:

  • コンテンツ本文に statuscode フィールドを追加する
  • 応答のステータスコードを 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とを処理しないことです。これは非常にハックな感じがするので、問題に対処するためのより良い方法があるに違いないと感じています。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

SendAsyncコンテンツを XML または JSON (独自のクラスにその機能をカプセル化できます) として解析できます。これにより、形式に関係なく (知る必要がないという意味で独立して) フィールドを追加できます。

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);
}
于 2011-06-11T01:39:10.813 に答える