如何避免发送 Http Headers 后出现状态错误?

问题描述 投票:0回答:1

我有一个使用 HttpGet 调用的 API。 API 验证调用并直接返回报告文件(Excel 或 CSV)。如果验证失败,它会返回一个 Json

Result
对象,其中包含错误代码和消息。

这是API函数:

<HttpGet>
Public Function AdvReport(APIKey As String, SubID As String) As Object
    Dim lRes As New Result

    Try
        ' Check Key
        If APIKey Is Nothing OrElse APIKey.Length = 0 Then Return lRes.Init(Result.ResultCode.NoAction, "API Key is missing")
        lRes = APIKeyClass.APIHit(APIKey)
        If lRes.NoSuccess Then Return lRes

        ' Get RepID
        If String.IsNullOrEmpty(SubID) Then Return lRes.Init(Result.ResultCode.NoAction, "SubID is missing")
        SubID = Encrypter.Decrypt(SubID)
        If SubID.Length = 0 OrElse Not IsNumeric(SubID) Then Return lRes.Init(Result.ResultCode.NoAction, "Invalid SubID")

        ' Load Advanced Report Subscription 
        Dim lSub As New AdvRepSubClass
        lRes = lSub.Load(CInt(SubID))
        If lRes.NoSuccess Then Return lRes

        If Not lSub.API Then Return lRes.Init(Result.ResultCode.NoAction, "Report not enabled for API access")

        ' Generate report
        If lRes.IsSuccess Then lRes = lSub.GetReportBin(Nothing, False)

        If lRes.IsSuccess Then LogClass.Log(Nothing, "API AdvReport", "Report Name: " + lSub.Title + "; Result: " + If(lRes.IsSuccess, "Success; Rows Affected: " + lRes.RowsAffected.ToString, lRes.Info) + "; API Key: " + APIKey, LogClass.LogTable.AdvRep, lSub.AdvRepID)

        ' Download it
        Try
            DownloadByteArray(CType(lRes.RetInfo, Byte()), GetReportFileName(lSub.Title, lSub.RepType), False)
            Return Nothing
        Catch ex As Exception
            lRes.Init(Result.ResultCode.Err, ex.Message)
        End Try

        Return lRes

    Catch ex As Exception
        Return lRes.Init(Result.ResultCode.Err, ex.Message)
    End Try
End Function

这是代码

DownloadByteArray()

Public Sub DownloadByteArray(aContent As Byte(), aFileName As String, aPreview As Boolean)

    Try
        HttpContext.Current.Response.Buffer = False
        HttpContext.Current.Response.Clear()
        HttpContext.Current.Response.AddHeader("Content-Disposition", If(aPreview, "inline", "attachment") + "; filename=""" & aFileName & """")
        If aPreview Then HttpContext.Current.Response.ContentType = Helper.GetContentType(aFileName) Else HttpContext.Current.Response.ContentType = "application/octet-stream"
        HttpContext.Current.Response.AddHeader("Content-Length", aContent.Length.ToString())
        HttpContext.Current.Response.BinaryWrite(aContent)
        HttpContext.Current.Response.Flush()
        HttpContext.Current.Response.SuppressContent = True
        HttpContext.Current.ApplicationInstance.CompleteRequest()
    Catch ex As Exception
        Dim lUserID As String = If(HttpContext.Current.Session IsNot Nothing AndAlso HttpContext.Current.Session("UserID") IsNot Nothing, HttpContext.Current.Session("UserID").ToString, Nothing)
        LogClass.Log(Nothing, lUserID, "DownloadByteArray", String.Concat("Doc: ", aFileName, "; Ex: ", ex.ToString()))
    End Try
End Sub

代码运行良好,并且使用 API 调用在浏览器上成功下载文件。问题是,在 API 调用后,全局应用程序错误处理程序也会被触发并出现以下错误:

System.Web.HttpException (0x80004005): Server cannot set status after HTTP headers have been sent. at System.Web.HttpResponse.set_StatusCode(Int32 value) at System.Web.Http.WebHost.HttpControllerHandler.<CopyResponseStatusAndHeadersAsync>d__31.MoveNext()

我明白该错误的含义。我假设该函数在发送 Http 标头后尝试将返回值设置为 Nothing。如何解决此问题并在文件发送后以某种方式“停止”该功能?

asp.net vb.net http-headers http-get
1个回答
0
投票

我通过不调用通用下载函数并仅内联写入文件返回来解决了该问题。

' If file required, download it
Try
    Dim lResult As New HttpResponseMessage(HttpStatusCode.OK)
    lResult.Content = New ByteArrayContent(CType(lRes.RetInfo, Byte()))
    lResult.Content.Headers.ContentDisposition = New ContentDispositionHeaderValue("attachment") With {
        .FileName = GetReportFileName(lSub.Title, lSub.RepType)
    }
    lResult.Content.Headers.ContentType = New MediaTypeHeaderValue("application/octet-stream")
    Return lResult
Catch ex As Exception
    lRes.Init(Result.ResultCode.Err, ex.Message)
End Try
© www.soinside.com 2019 - 2024. All rights reserved.