Как устранить ошибку «Сервер не может установить статус после отправки заголовков HTTP» при попытке загрузки файлов через вызов web api? - PullRequest
0 голосов
/ 02 апреля 2019

Когда я использую вызов web api для загрузки файла, я могу легко загрузить файл.Единственная проблема заключается в том, что я получаю Сервер не может установить статус после отправки заголовков HTTP в мои журналы ошибок.Извините, если это потенциально повторяющийся вопрос, но ни один из приведенных здесь ответов не помог мне.

<a href="/api/DownloadDocumentById?documentId=<%=doc.Id %>" download>
                                    <i class="fa fa-download text-primary"></i>
                                </a>
<HttpGet>
    <ActionName("DownloadDocumentById")>
    Public Function DownloadDocumentById(documentId As Integer)
        Dim document = xxxxxxxx

        Dim context = HttpContext.Current

        context.Response.ContentType = document.Type

        context.Response.OutputStream.Write(document.Content, 0, document.Size)

        context.Response.AddHeader("Content-Disposition", Baselib.FormatContentDispositionHeader($"{document.Name}"))

        context.Response.AddHeader("Last-Modified", DateTime.Now.ToLongDateString())

        context.Response.Flush()

        context.Response.End()

        Return HttpStatusCode.OK // Have also tried to create a sub without returning a value
    End Function

Как уже упоминалось ранее, я могу легко загрузить документ, но все равно логи IIS Серверневозможно установить статус после отправки заголовков HTTP ошибка.Снова извините за этот вопрос дубликат.Надеюсь, кто-нибудь может мне помочь.

1 Ответ

2 голосов
/ 02 апреля 2019

Прежде всего, я думаю, что вы должны добавить все заголовки, прежде чем начнете писать фактический вывод / контент.С буферизованным потоком (что я и собираюсь предложить) это не должно иметь никакого значения и является в основном только семантическим, но поскольку заголовки должны быть добавлены до записи контента (контент всегда последний)может избежать подобных проблем в будущем, если вы решите использовать небуферизованный поток.

Поэтому я предлагаю вам изменить порядок кода соответствующим образом:

context.Response.ContentType = document.Type

context.Response.AddHeader("Content-Disposition", Baselib.FormatContentDispositionHeader($"{document.Name}"))
context.Response.AddHeader("Last-Modified", DateTime.Now.ToLongDateString())

context.Response.OutputStream.Write(document.Content, 0, document.Size)

Теперь, если вы используете небуферизованный потоксодержимое будет отправлено клиенту сразу же после того, как вы вызовете OutputStream.Write(), поэтому для того, чтобы впоследствии установить результат HTTP, вам необходимо убедиться, что весь ваш ответ буферизирован, чтобы он не отправлялся до вашего внутреннего запроса (действие иконтроллер) завершил выполнение.Это можно сделать, установив Response.BufferOutput на True перед выводом чего-либо:

context.Response.BufferOutput = True

context.Response.ContentType = document.Type

'The rest of the code...

Наконец, вам нужно удалить вызовы на Response.Flush() и Response.End(), так как онипреждевременно очистите буфер и напишите все клиенту, прежде чем вы сможете вернуть код состояния.

Новый код:

(...)

context.Response.BufferOutput = True

context.Response.ContentType = document.Type

context.Response.AddHeader("Content-Disposition", Baselib.FormatContentDispositionHeader($"{document.Name}"))
context.Response.AddHeader("Last-Modified", DateTime.Now.ToLongDateString())

Return HttpStatusCode.OK
...