ASP.NET MVC - 在升级到.NET 4.0后,View中的Response.Clear()无法正常工作

时间:2013-05-24 21:09:31

标签: asp.net asp.net-mvc

我刚刚将ASP.NET项目从.NET 2.0升级到4.0。仍在使用MVC 2.发送回.csv文件的一些功能(奇怪地)写为视图。然后,在MainContentPlaceHolder部分中,代码丢弃了Master中的所有内容:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/MyMaster" Inherits="System.Web.Mvc.ViewPage<MyViewModel>" %>

<%
    HttpContext context = HttpContext.Current;
    context.Response.Clear();
    context.Response.Write(Html.CompletionByTemplateExport((CompletionByTemplateExport)ViewData["report"]));
    context.Response.ContentType = "text/csv";
    context.Response.AppendHeader("Content-Disposition", "attachment; filename=CompletionByTemplateReport.csv");
    context.Response.End();
 %>

升级到.NET 4.0后,此解决方法不再起作用:.csv文件包含母版页输出的所有html内容。

在升级到.NET 4.0时,处理请求和响应的方式发生了哪些变化?有没有办法让它表现得很旧,所以response.Clear()和Response.End()像往常一样工作?我正在寻找一个短期解决方案,直到可以重写.csv下载功能。

2 个答案:

答案 0 :(得分:2)

我不确定如何,但看起来似乎.NET 2.0和.NET 4.0之间的页面生命周期略有变化。我能够复制这个问题。

我认为你的观点看起来像这样:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/MyMaster" Inherits="System.Web.Mvc.ViewPage<MyViewModel>" %>

<asp:Content Id="MainContent1" ContentPlaceHolderID="MainContent">
<%
    HttpContext context = HttpContext.Current;
    context.Response.Clear();
    context.Response.Write(Html.CompletionByTemplateExport((CompletionByTemplateExport)ViewData["report"]));
    context.Response.ContentType = "text/csv";
    context.Response.AppendHeader("Content-Disposition", "attachment; filename=CompletionByTemplateReport.csv");
    context.Response.End();
 %>
</asp:Content>

不幸的是,我相信你必须做这样的事情:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/MyMaster" Inherits="System.Web.Mvc.ViewPage<MyViewModel>" %>

<script runat="server">
void Page_Load(object sender, EventArgs args) {
    HttpContext context = HttpContext.Current;
    context.Response.Clear();
    context.Response.Write(Html.CompletionByTemplateExport((CompletionByTemplateExport)ViewData["report"]));
    context.Response.ContentType = "text/csv";
    context.Response.AppendHeader("Content-Disposition", "attachment; filename=CompletionByTemplateReport.csv");
    context.Response.End();
 }
</script>

或(更好),将该代码移动到控制器中(因为这是MVC):

public class MyController : Controller
{
    public ActionResult Index()
    {
        // This is redundant, Controllers and Views have a Response property
        // HttpContext context = HttpContext.Current;
        CompletionByTemplateExport reportData = ...;
        Response.Clear();
        Response.Write(Html.CompletionByTemplateExport(reportData));
        Response.ContentType = "text/csv";
        Response.AppendHeader("Content-Disposition", "attachment; filename=CompletionByTemplateReport.csv");
        Response.End();   
    }
}

其中任何一个都只会为您提供没有母版HTML的CSV。

答案 1 :(得分:0)

我通过添加指示文件大小的标题解决了类似的问题。

这对我没有意义,但它确实有效。

With Response
    .Buffer = True
    .ClearContent()
    .ClearHeaders()        
    .ContentType = "text/csv"
    .AppendHeader("content-disposition", "attachment;  filename=" & fileName)
    .AppendHeader("Content-Length", buffer.Length)
    .OutputStream.Write(buffer, 0, buffer.Length)
    .Flush()
End With