ASP.NET:为什么我会得到另一个标题而不是我设置的标题?

时间:2014-02-25 16:10:59

标签: c# asp.net .net vb.net google-chrome

我有一个恼人的问题: 我应该在浏览器中显示PDF(内联显示,而不是下载)。

到目前为止,使用下面的代码,它适用于Internet Explorer。 但在google-chrome中,它只是下载。

在同一台服务器上,执行相同操作的第三方应用程序正常工作。
我想问题是你在内容类型标题中看到的“appliction / octet-stream”......

我觉得这很烦人。
我的代码设置了内容类型application / pdf,当我查看发送的实际标题时,我看到它是application / octet-stream ......

根据 https://superuser.com/questions/219870/how-to-open-pdf-in-chromes-integrated-viewer-without-downloading-it#

这是因为mime是八位字节流而不是application / pdf ...

我只有一个问题:为什么?为什么?为什么? (为什么设置八位字节流,而不是代码中设置的application / pdf - 请参阅下面的完整代码)
额外的问题:如果我将Content-Length设置为字节数组的长度,为什么Transfer-Encoding会被分块?

有趣的是,它在我的本地开发服务器上工作正常,所以这似乎与IIS的罪恶有关> = 7 ...

Bad HTTP Headers

ashx:

    Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        Dim baPDF As Byte() = GetPdfFromImage(Me.Data)
        'context.Response.Write(COR.Tools.JSON.JsonHelper.Serialize(Me.Data(context)))

        context.Response.Clear()
        'context.Response.AddHeader("Content-Disposition", "attachment; filename=" + strFileName)
        context.Response.AddHeader("Content-Disposition", Portal.ASP.NET.GetContentDisposition("Drucken.pdf", "inline"))
        context.Response.AddHeader("Content-Length", baPDF.Length.ToString())
        ' context.Response.ContentType = "application/msword"
        ' context.Response.ContentType = "application/octet-stream"

        ' https://superuser.com/questions/219870/how-to-open-pdf-in-chromes-integrated-viewer-without-downloading-it#
        ' context.Response.ContentType = "text/html"
        context.Response.ContentType = "application/pdf"



        context.Response.BinaryWrite(baPDF)
        context.Response.Flush()

        context.Response.End()
    End Sub





    ' COR.ASP.NET.StripInvalidPathChars("") '
    Public Shared Function StripInvalidPathChars(str As String) As String
        Dim strReturnValue As String = Nothing

        If str Is Nothing Then
            Return strReturnValue
        End If

        Dim sb As System.Text.StringBuilder = New System.Text.StringBuilder()
        Dim achrInvalidPathChars As Char() = System.IO.Path.GetInvalidPathChars()


        For Each cThisChar As Char In str
            Dim bIsValid As Boolean = True

            For Each cInvalid As Char In achrInvalidPathChars
                If cThisChar = cInvalid Then
                    bIsValid = False
                    Exit For
                End If
            Next cInvalid

            If bIsValid Then
                sb.Append(cThisChar)
            End If
        Next cThisChar

        strReturnValue = sb.ToString()
        sb = Nothing
        Return strReturnValue
    End Function ' StripInvalidPathChars '


    Public Shared Function GetContentDisposition(ByVal strFileName As String) As String
        Return GetContentDisposition(strFileName, "attachment")
    End Function ' GetContentDisposition '


    ' http://www.iana.org/assignments/cont-disp/cont-disp.xhtml '
    Public Shared Function GetContentDisposition(ByVal strFileName As String, ByVal strDisposition As String) As String
        ' http://stackoverflow.com/questions/93551/how-to-encode-the-filename-parameter-of-content-disposition-header-in-http '
        Dim contentDisposition As String
        strFileName = StripInvalidPathChars(strFileName)

        If String.IsNullOrEmpty(strDisposition) Then
            strDisposition = "inline"
        End If

        If System.Web.HttpContext.Current IsNot Nothing AndAlso System.Web.HttpContext.Current.Request.Browser IsNot Nothing Then
            If (System.Web.HttpContext.Current.Request.Browser.Browser = "IE" And (System.Web.HttpContext.Current.Request.Browser.Version = "7.0" Or System.Web.HttpContext.Current.Request.Browser.Version = "8.0")) Then
                contentDisposition = strDisposition + "; filename=" + Uri.EscapeDataString(strFileName).Replace("'", Uri.HexEscape("'"c))
            ElseIf (System.Web.HttpContext.Current.Request.Browser.Browser = "Safari") Then
                contentDisposition = strDisposition + "; filename=" + strFileName
            Else
                contentDisposition = strDisposition + "; filename*=UTF-8''" + Uri.EscapeDataString(strFileName)
            End If
        Else
            contentDisposition = strDisposition + "; filename*=UTF-8''" + Uri.EscapeDataString(strFileName)
        End If

        Return contentDisposition
    End Function ' GetContentDisposition '

这是第三方应用程序的标题,Chrome显示正常 Aperture Headers

2 个答案:

答案 0 :(得分:1)

解决方案就像它很可怕一样简单。

感谢同事的更改,代码直接在ashx文件中,而不是在ashx.vb中。

这很好的部分是,即使您有一个已编译的Web应用程序,也可以修改服务器上的ashx。 不好的是,这与网站项目即时编译具有相同的效果。

因此,当您重新编译应用程序并将MyWebApplication.dll放到服务器上时,这将保留旧的ashx。

由于ASP.NET使用ashx中的代码而不是编译的dll,因此只要不更新ashx文件,它总是使用旧代码。

立即更改,立即开始工作 现在,这是一个很好的... ... 代码中从未出现过错误。

答案 1 :(得分:0)

在设置所需的标题之前,您需要清除标题。

Microsoft's page关于Response.Clear

  
    

Clear方法不会清除标题信息。

  
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
    Dim baPDF As Byte() = GetPdfFromImage(Me.Data)

    context.Response.ClearHeaders()
    context.Response.ContentType = "application/pdf"

    ... ' Cut for brevity
End Sub