2012-01-11 124 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 2012-01-11 10:24:43

+0

@DenisPostu當我關閉響應時,請求無法完成 – 2012-01-11 10:30:11

+0

也許你可以描述你正在嘗試完成什麼,以及你在不需要的響應中得到了什麼? – 2012-01-11 12:10:03

回答

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,非常感謝,但這並不是我所需要的。它只是繼續進行管道中的常規操作,而我得到相同的結果 – 2012-01-11 12:00:04