2009-10-19 7 views
3

ASP.NET 페이지에서 브라우저로 파일을 보내고 있습니다. 제대로 내가 헤더를 추가하고 파일 이름을 보내려면 :ASP.NET 파일 인코딩 중 파일 인코딩

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

문제는 파일에 공백이 포함 된 경우 (예를 들어 "ABC 데프") 브라우저가 파일 이름의 "ABC"부분을받는 것입니다. 나는 Server.HtmlEncode와 함께 시도했지만 도움이되지 않았다.

이 문제를 해결하는 방법을 알고 계십니까?

+0

Server.UrlEncode – Arthur

답변

9

PK 따옴표로 파일 이름을 넣어 : -

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

이를 UrlEncode하지 마십시오. 이것은 HTTP 구조화 된 헤더 매개 변수에 사용할 값을 이스케이프 처리하는 올바른 방법이 아닙니다. 그것은 그 브라우저의 버그 처리 때문에 심지어는 IE에서 작동하고 심지어 안정적으로 작동하지 않습니다.

공간의 경우 Anthony (+1)의 제안에 따라 인용 문자열을 사용할 수 있습니다. 그러나 Content-Disposition의 더러운 진실은 ;, " 또는 유니 코드 문자와 같은 임의의 문자를 filename 매개 변수에 넣는 데 사용할 수있는 신뢰할 수 있고 지원되는 이스케이프 스키마가 없다는 것입니다. 신뢰할 수있는 크로스 브라우저로 작동하는 유일한 방법은 파일 이름 매개 변수를 완전히 삭제하고 원하는 파일 이름을 URI에 후행 UTF-8 + URL 인코딩 경로 부분으로 넣는 것입니다.

일부 배경에 대해서는 this answer을 참조하십시오.

+0

일반적으로 Windows 환경에서; 어쨌든 유효한 파일 이름 문자가 아닙니다. 필자는이 파일 이름 매개 변수를 사용하는 모든 것을 "legal-in-filename"sanitizer를 통해 이러한 문자를 추출하는 경향이 있습니다. – 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