3

我刚刚将一个 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 下载功能。

4

2 回答 2

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。

于 2013-06-06T16:15:10.027 回答
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
于 2017-08-26T04:26:28.943 回答