2012-01-11 16 views
1

私はカスタムActionFilterAttributeを書き、ASP.NET MVC 3の出力ストリームに直接データを書き込もうとしています。私が書いているデータは、書いた後にデータレンダリングビューの後に余分なデータがあります。私はOutputStreamを閉じようとしていますが、それでもまだ書いておくことができます。書き込みのためにこのストリームを閉じたり、HTMLレンダリングの後で無視するにはどうすればよいですか?HttpWebResponse出力ストリームが閉じない

public override void OnActionExecuted(ActionExecutedContext filterContext) 
{ 
    var request = filterContext.RequestContext.HttpContext.Request; 
    var acceptTypes = request.AcceptTypes ?? new string[] {}; 
    var response = filterContext.HttpContext.Response; 

    if (acceptTypes.Contains("application/json")) 
    { 
     response.ContentType = "application/json"; 
     Serializer.Serialize(data, response.ContentType, response.OutputStream); 
    } 
    else if (acceptTypes.Contains("text/xml")) 
    { 
     response.ContentType = "text/xml"; 
     Serializer.Serialize(data, response.ContentType, response.OutputStream); 
    } 
    response.OutputStream.Close(); 
} 


UPDは、例えば、私のデータは{"Total": 42, "Now": 9000}
で、私の見解が応答でこの

<div> 
    <span>The data that shouldn't be here</span> 
</div> 

のようなものです私は

{"Total": 42, "Now": 9000} 
<div> 
    <span>The data that shouldn't be here</span> 
</div> 

を取得し、それが有効なJSONではありませんご覧のように。私の目的はJSONまたはXMLのみを送信することです

+0

応答を閉じるときにOutputStream – DenisPostu

+0

@DenisPostuを試してください。要求を完了できません。 –

+0

あなたは何を達成しようとしているのでしょうか? –

答えて

0

大きな努力の後、私は自分の要求に合った決定を見つけました。それは問題の先頭にあった。私が必要とするのは、それを閉じる前に応答を洗い流すことだけです。しかし、この場合、Content-Length HTTPヘッダーが欠落し、コンテンツの長さが応答本体に正しく書き込まれます。したがって、応答をフラッシングする前に、このヘッダを手動で設定する必要があります。

public override void OnActionExecuted(ActionExecutedContext filterContext) 
{ 
    var request = filterContext.RequestContext.HttpContext.Request; 
    var acceptTypes = request.AcceptTypes ?? new string[] {}; 
    var response = filterContext.HttpContext.Response; 

    if (acceptTypes.Contains("application/json")) 
    { 
     WriteToResponse(filterContext, data, response, "application/json"); 
    } 
    else if (acceptTypes.Contains("text/xml")) 
    { 
     WriteToResponse(filterContext, data, response, "text/xml"); 
    } 
} 

private void WriteToResponse(ActionExecutedContext filterContext, object data, HttpResponseBase response, String contentType) 
{ 
    response.ClearContent(); 
     response.ContentType = contentType; 
     var length = Serializer.Serialize(data, response.ContentType, response.OutputStream); 
     response.AddHeader("Content-Length", length.ToString()); 
     response.Flush(); 
     response.Close(); 
} 

ストリームはSerializer.Serializeによってそこに書き込まれ、この方法は、出力ストリームに書き込まれたコンテンツの長さを返します。

1

ASP.NETパイプラインは応答オブジェクトのライフサイクルを管理します。ストリームを突然終了させたり応答を終了したりする場合、ダウンストリームのコンポーネントは書き込みを試みると失敗します。

システムに応答を強制的に終了させる場合は、HttpApplication.CompleteRequest()に電話する必要があります。それはASP.NETパイプラインの残りのイベントをバイパスするので、望ましくない副作用がないわけではありませんが、推奨される方法です。

詳細情報はhereです。

+0

@Programming_Hero大変ありがとうございます。それはパイプラインで通常のアクションを実行し続けるだけで、私は同じ結果を得ます –

関連する問題