我正在从ASP.NET页面向浏览器发送文件。要正确发送文件名,我正在添加标题:
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
问题是当文件包含空格(例如“abc def”)时,浏览器只接收文件名的“abc”部分。我试过:Server.HtmlEncode但它没有帮助。
你知道如何解决这个问题吗?
PK
答案 0 :(得分:9)
将文件名放在引号中: -
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
答案 1 :(得分:4)
不要UrlEncode。这不是在HTTP结构化标头参数中转义值的正确方法。它只适用于IE,因为浏览器的错误处理,甚至不可靠。
对于空格,您可以使用Anthony(+1)建议的带引号的字符串。但Content-Disposition的肮脏事实是,没有可靠的,支持的转义方案可用于在filename参数中放置;
,"
或Unicode字符等任意字符。可靠地跨浏览器工作的唯一方法是完全删除filename参数,并将所需的文件名作为尾随的UTF-8 + URL编码路径部分放在URI中。
有关背景信息,请参阅this answer。
答案 2 :(得分:1)
某些浏览器不支持带有特殊符号的文件名(例如:space;#@!$)或非Unicode字符,或者导致客户端计算机中的文件名不正确。 这是一篇名为chanext的中文文章,他给出了解决这个问题的完美方法: 本文给出了一个示例代码(用c#编写),以展示如何在所有四种流行的浏览器(IE; Opera; Firefox和Chrome)中获得完美的解决方案 文件名“Microsoft.Asp.Net.doc”和“F ile ;;!@%#^& y.doc”都可以使用作者在本文中提供的方式正确输出。
http://ciznx.com/post/aspnetstreamdownloaddisplaynonunicodespacechar.aspx
答案 3 :(得分:0)
基于@chanext引用的代码,我将其清理干净并将其放入单个扩展方法中。希望这可以帮助别人。
Partial Class Uploader
Inherits Page
Private Sub UploadFile()
Dim sFileName As String
Dim oPdf As MigraDoc.Rendering.PdfDocumentRenderer
sFileName = "File Name With Spaces #22.pdf"
With Me.Request.Browser
If .Browser = "InternetExplorer" OrElse .Browser = "IE" Then
sFileName = sFileName.EncodeForIE
Else
sFileName = String.Format("""{0}""", sFileName)
End If
End With
oPdf = New MigraDoc.Rendering.PdfDocumentRenderer
oPdf.Document = FileFactory.CreatePdf()
oPdf.RenderDocument()
Using oStream As New MemoryStream
oPdf.Save(oStream, False)
Me.Response.Clear()
Me.Response.ContentType = "application/pdf"
Me.Response.AddHeader("content-disposition", String.Format("attachment; filename={0}", sFileName))
Me.Response.AddHeader("content-length", oStream.Length)
Me.Response.BinaryWrite(oStream.ToArray)
End Using
Me.Response.Flush()
Me.Response.End()
End Sub
End Class
Public Module StringExtensions
<Extension()>
Public Function EncodeForIE(Url As String) As String
Dim _
sReservedChars,
sEncodedString As String
sReservedChars = "$-_.+!*'(),@=&"
With New StringBuilder
Url.ToList.ForEach(Sub(C)
If Char.IsLetterOrDigit(C) OrElse sReservedChars.Contains(C) Then
.Append(C)
Else
With New StringBuilder
C.ToBytes.ToList.ForEach(Sub(B)
.AppendFormat("%{0}", Convert.ToString(B, 16))
End Sub)
sEncodedString = .ToString
End With
.Append(sEncodedString)
End If
End Sub)
Return .ToString
End With
End Function
<Extension()>
Public Function ToBytes(Chr As Char) As Byte()
Return Encoding.UTF8.GetBytes(Chr.ToString)
End Function
End Module