2010-12-27 1 views
5

フィールドにあるレガシーアプリケーションをサポートするには、空のレスポンスを返すようにASP.NET MVCアプリが必要です(Content-Type)。ヌル応答を返信すると、IIS、ASP.NET、またはASP.NET MVCのいずれかがContent-Typeを削除しています。これを回避する方法はありますか?ASP.NET MVCで空のレスポンスのContent-Typeを設定する

EDIT(セットで空の応答を必要としないがContent-Type明らかに理想的なソリューションは、クライアントはそこに既にあり、そしてそれらの多くはアップグレードできないだろう。):があったので、コードのリクエスト:新しいWebアプリケーションのリクエストを、古いクライアントが依存するリクエストにプロキシしています。これを行うには、LegacyResultと呼ばれるサブクラスActionResultがあります。これは、古いソフトウェアで処理する必要のあるメソッドに簡単に戻ることができます。これは、そのコードの関連する部分である:

public override void ExecuteResult(ControllerContext context) 
    { 
     using (var legacyResponse = GetLegacyResponse(context)) 
     { 
      var clientResponse = context.HttpContext.Response; 
      clientResponse.Buffer = false; 
      clientResponse.ContentType = legacyResponse.ContentType; /* Yes, I checked that legacyResponse.ContentType is never string.IsNullOrEmpty */ 
      if (legacyResponse.ContentLength >= 0) clientResponse.AddHeader("Content-Length", legacyResponse.ContentLength.ToString()); 

      var legacyInput = legacyResponse.GetResponseStream(); 
      using (var clientOutput = clientResponse.OutputStream) 
      { 
       var rgb = new byte[32768]; 
       int cb; 
       while ((cb = legacyInput.Read(rgb, 0, rgb.Length)) > 0) 
       { 
        clientOutput.Write(rgb, 0, cb); 
       } 
       clientOutput.Flush(); 
      } 
     } 
    } 

legacyInputにデータがある場合には、Content-Typeが適切に設定されています。そうでなければ、そうではありません。私は実際に古いバックエンドをクルーグして、まったく同じ要求に対して空のvと空でない応答を送信し、Fiddlerの違いを観察できます。

EDIT 2:リフレクターとチャンスをうかがっヘッダがHttpResponse.Flushが呼び出された時点で書き込まれていない場合は、その後、Flushはヘッダ自体を書き出し、ことが明らかになりました。問題は、ヘッダーの小さなサブセットのみを書き出すことです。欠落しているものの1つはContent-Typeです。だから、私がストリームにヘッダーを強制することができれば、私はこの問題を回避することができます。

+0

は、あなたのコードをしてください表示します。 –

+0

空の流れをフラッシュしているのだろうか? 'ContentType'を設定した後にすべてをコメントアウトするとどうなりますか? –

+0

'ContentType'の後のすべてをコメントアウトすると違いはありません。行動は同じです。これは、 'Flush'がまだ呼び出されているからですが、ASP.NETスタック内のどこかで呼び出されてしまいます。 (言い換えれば、悪影響を与えずに線を取り除くことができるように見えるが、そのようにしても挙動は変化しないように思われる)。 –

答えて

8

あなたはsuppressing it、その後、誤ってコンテンツがあります、それを伝えることで、ヘッダを書くに応答を誘導しなけれ:

/// [inside the writing block] 
var didWrite = false; 
while ((cb = legacyInput.Read(rgb, 0, rgb.Length)) > 0) 
{ 
    didWrite = true; 
    clientOutput.Write(rgb, 0, cb); 
} 
if (!didWrite) 
{ 
    // The stream needs a non-zero content length to write the correct headers, but... 
    clientResponse.AddHeader("Content-Length", "1"); 
    // ...this actually writes a "Content-Length: 0" header with the other headers. 
    clientResponse.SuppressContent = true; 
} 
関連する問題