2009-10-19 6 views
3

Я отправляю файл с страницы ASP.NET в браузер. Чтобы правильно отправить имя файла Я добавляю заголовок:ASP.NET кодировка имени файла при отправке файла

Response.ContentType = "application/octet-stream"; 
Response.AddHeader("Content-Disposition", "attachment; filename=" + filename); 

Проблема заключается в том, что, когда файл содержит пробелы (например, «ABC DEF») браузер получает только «ABC» часть имени файла. Я пробовал с: Server.HtmlEncode, но это не помогло.

У вас есть идеи, как решить эту проблему?

PK

+0

Server.UrlEncode – Arthur

ответ

9

Поместите имя файла в кавычки: -

Response.ContentType = "application/octet-stream"; 
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + filename + "\""); 
4

Не UrlEncode. Это неправильный способ избежать значения для использования в параметре структурированного заголовка HTTP. Он работает только в IE из-за ошибок в работе браузера, и даже тогда не надежно.

В качестве пробела вы можете использовать строку с цитатами, предложенную Энтони (+1). Но грязная правда Content-Disposition заключается в том, что нет надежной поддерживаемой схемы экранирования, которая может использоваться для размещения произвольных символов, таких как ;, " или символов Unicode в параметре имени файла. Единственный подход, который работает над перекрестным браузером, - это полностью отказаться от параметра имени файла и поместить желаемое имя файла в URI в качестве конечной части пути с кодировкой URL-адреса UTF-8 +.

См. this answer для фона.

+0

Обычно в среде windows; в любом случае, не является действительным символом имени файла. Я склонен вкладывать все, что использует этот параметр filename через дезинфицирующее средство «legal-in-filename», чтобы вытаскивать такие символы. – AnthonyWJones

1

Имя файла со специальными символами (например: пробел; # @! $) Или символы не-Юникода либо не могут поддерживаться некоторыми браузерами, либо вызывать неправильное имя файла на клиентской машине. Вот статья китайца по имени chanext, он дал отличный способ решить эту проблему: В этой статье приведен пример кода (написанный с помощью C#), чтобы показать, как получить идеальное решение этой проблемы во всех четырех популярных браузерах (IE, Opera, Firefox и Chrome) имя файла «Microsoft.Asp.Net.doc» и «F ile ;;! @% #^& y.doc» может быть выведено правильно, используя способ, предоставленный автором в этой статье ,

http://ciznx.com/post/aspnetstreamdownloaddisplaynonunicodespacechar.aspx

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 
Смежные вопросы