如何使用Response发送多个文件。 ASP.NET

时间:2017-11-30 13:34:20

标签: asp.net

我试图在循环中调用下面的代码数百次:

   Sub ExportReport(ByVal en As MyReport)
        Dim warnings As Warning() = Nothing
        Dim streamids As String() = Nothing
        Dim mimeType As String = Nothing
        Dim encoding As String = Nothing
        Dim extension As String = Nothing
        Dim bytes As Byte()
            bytes = aReport.ServerReport.Render("WORD", Nothing, mimeType, encoding, extension, streamids, warnings)


        Response.Buffer = True
        Response.Clear()
        Response.ContentType = mimeType
        Response.AddHeader("content-disposition", "attachment; filename=" & en.ToString() & "." + extension)
        Response.BinaryWrite(bytes)
        Response.Flush()
        Response.End()

    End Sub

我收到了这个错误:

  

在发送HTTP标头后,服务器无法追加标头。

如何更改代码以便我可以循环这段代码?感谢。

编辑: 我在Response.End()

之后添加了这一行
Response.Redirect(Request.Url.AbsoluteUri)

我收到了这个错误:

  

发送HTTP标头后无法重定向。

2 个答案:

答案 0 :(得分:1)

WWW处理请求/响应机制。对于每个请求,只有1个响应。你无法改变这种基本机制。当浏览器发送请求时,它期待一个且只有一个响应。因此,如果它收到多于1个响应,它会向用户发出警告以阻止此行为,或者可以选择单独忽略额外响应。因此,这些额外的反应可能会丢失。

说过你有两个选择:

  1. 将您要下载的所有文件压缩并下载为单个文件。
  2. 您可以使用热门框架Ionic.Zip

    首先,将所有文件保存在服务器上的本地目录中。 然后使用此库来压缩整个文件夹。

    伪代码:

    Imports (var zip = New Ionic.Zip.ZipFile())
    {
       zip.AddDirectory("DirectoryOnDisk", "rootInZipFile")
       Response.Clear()
       Response.AddHeader("Content-Disposition", "attachment; filename=DownloadedFile.zip")
       Response.ContentType = "application/zip"
       zip.Save(Response.OutputStream)
       Response.End()
    }
    
    1. 添加一种机制,使用Javascript发出多个请求以获取多个响应,因此浏览器仍然会将此行为视为正常。

答案 1 :(得分:0)

普通网页已经为您设置了一些(标题)内容,但您不需要这些内容:您希望完全控制发送到浏览器的内容。如果您导致重定向到稍后在此处发送代码中显示的标题的内容,浏览器将(通常)下载数据。

在代码隐藏中,您可以使用类似

的内容
Protected Sub btn_click(ByVal sender As Object, ByVal e As EventArgs) Handles btn.Click
    Response.Redirect("~/sendfile.ashx?ref=" & enReference, False)
    Context.ApplicationInstance.CompleteRequest()

End Sub

您还需要添加一个通用处理程序(右键单击解决方案资源管理器中的项目,添加 - >新项目... - > Visual Basic - Web - 常规选择“Generic Handler”;给出它像sendfile.ashx这样的名字,有点像

Imports System.IO

Public Class sendfile
    Implements System.Web.IHttpHandler, IReadOnlySessionState

    Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest

        Dim enReference = context.Request.QueryString("ref")
        ' do whatever is needed to get the report from enReference '
        Dim bytes As Byte() = aReport.ServerReport.Render("WORD", Nothing, mimeType, encoding, extension, streamids, warnings)
        Dim downloadName = yourfilename & "." & yourextension

        context.Response.ContentType = "application/octet-stream"
        context.Response.AddHeader("content-disposition", "attachment; filename=""" & downloadName & """"  )
        context.Response.BinaryWrite(bytes)

    End Sub

    ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property

End Class

您将需要计算代码来创建要发送的数据。

如果您不需要使用会话状态,则可以删除, IReadOnlySessionState行上的Implements部分。

可能需要添加context.Response.Flush()。如果您发现响应没有Content-Length标头,那么您应该添加一个,以便浏览器可以显示有意义的下载进度。