HttpWebResponse输出流没有';t关闭

本文关键字:关闭 输出流 HttpWebResponse | 更新日期: 2023-09-27 18:20:03

我正在编写自定义ActionFilterAttribute,并试图在ASP.NET MVC 3中直接将一些数据写入输出流。我正在编写的数据是我所需要的全部响应,但在编写之后,在我的数据呈现视图之后还有一个额外的数据。我正在尝试关闭OutputStream,但它仍然可以用于写作。如何关闭此流进行编写或忽略以下HTML呈现?

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

HttpWebResponse输出流没有';t关闭

ASP.NET管道管理响应对象的生命周期。如果突然关闭流或结束响应,下游组件在尝试写入时将失败。

如果要强制系统结束响应,则应调用HttpApplication.CompleteRequest()。它将绕过ASP.NET管道中的其余事件,因此它并非没有潜在的不必要的副作用,但它是推荐的方法。

更多信息可以在这里找到。

经过大量的努力,我找到了适合我需求的决定。这是最重要的问题。我所需要的只是在关闭响应之前刷新它。但在这种情况下,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写入的,该方法还返回在输出流中写入的内容的长度。