Trouble with Response.WriteFile / Response.BinaryW

2019-05-28 04:02发布

问题:

I've got a simple web-page that generates a CSV file that I want the user to be able to download once its creation is complete.

Here's a summary of my situation:

  1. The CSV file can be created in-memory or on disk. Doesn't matter to me.
  2. Once I'm done transmitting the CSV file, I do not want it to continue residing on disk.
  3. I've tried various code using Response.WriteFile, .TransmitFile, .BinaryWrite and .Write, but to no avail.
  4. When I say "to no avail", I mean that rather than the CSV file being transmitted, I'm transmitting the contents of the CSV file PLUS THE ENTIRETY OF THE CURRENT PAGE!
  5. I'm really confused since I have another page that's doing essentially the same thing, but with PDF files bundled in a zip file, and it works just fine.
  6. I'm really a Windows desktop developer, but I'm trying to become a web developer. (So sorry if this is a stupid or noob question.)

Here's the code I've got working to send the .zip containing PDF files:

Protected Sub SaveReportsButton_Click(sender As Object, e As EventArgs) Handles SaveReportsButton.Click
    '' The .zip file is created elsewhere
    Dim fullPath As String = Server.MapPath("~/Reports/" & Session.SessionID & ".zip")
    Response.ContentType = "APPLICATION/OCTET-STREAM"
    Dim fileToDownload As New FileInfo(fullPath)
    Dim disHeader As String = "Attachment; Filename=""Reports.zip"""
    Response.AppendHeader("Content-Disposition", disHeader)
    Response.Flush()
    Response.WriteFile(fileToDownload.FullName)
End Sub

Here's the code I'm trying to get working to transmit the CSV file:

Protected Sub saveButton_Click(sender As Object, e As System.EventArgs) Handles SaveOutput.Click
    Dim list As List(Of String) = {"000000000", "000000000", "000000000"}.ToList()
    Dim sb As New Text.StringBuilder
    For i As Integer = 0 To list.Count - 1
        Dim str As String = list(i)
        sb.Append(str)
        If i < list.Count - 1 Then
            sb.Append(",")
        End If
    Next
    Dim dirPath As String = Server.MapPath("~/Output/" & Session.SessionID)
    IO.Directory.CreateDirectory(dirPath)
    Dim filePath As String = Server.MapPath("~/Output/" & Session.SessionID & "/Output.csv")
    IO.File.WriteAllText(filePath, sb.ToString())
    Response.ContentType = "text/csv"
    Dim disHeader As String = "Attachment; Filename=""Output.csv"""
    Response.AppendHeader("Content-Disposition", disHeader)
    Response.Flush()
    Response.WriteFile(filePath)
End Sub

Like I said, I wish to limit the files created and left on the server by this page, so I'd like to get rid of the CSV file once I'm done with it.

Any help?

Thanks!!!

回答1:

try this with Response.Write and Response.End

Protected Sub saveButton_Click(sender As Object, e As System.EventArgs) Handles SaveOutput.Click
    Dim list As List(Of String) = {"000000000", "000000000", "000000000"}.ToList()
    Dim sb As New Text.StringBuilder
    For i As Integer = 0 To list.Count - 1
        Dim str As String = list(i)
        sb.Append(str)
        If i < list.Count - 1 Then
            sb.Append(",")
        End If
    Next
    Response.Clear()
    Response.ContentType = "text/csv"
    Dim disHeader As String = "Attachment; Filename=""Output.csv"""
    Response.AppendHeader("Content-Disposition", disHeader)
    Response.Flush()
    Response.Write(sb.ToString())
    Response.End()
End Sub


回答2:

You don't need to save this file at all. Why don't you just return the response and that's it. If you don't create file, you don't need to worry about deleting it.

Content is created on the fly.

UPDATE

set response header "content-disposition" and then write to Response.OutputStream

find out more about response header here http://www.jtricks.com/bits/content_disposition.html

in terms of c# code, do something like that

Response.AddHeader("content-disposition", string.Format("filename={0}", fileName));
using (var myWriter = new SOMETHING_WHICH_CAN_WRITE_TO_STREAM())
{
    myWriter.Write(Response.OutputStream);
}

Hope it helps