HttpResponseMessage.Содержание.Заголовки ContentDisposition имеет значение null
При загрузке файла с помощью HttpClient я загружаю сначала заголовки, а затем содержимое. Когда заголовки загружаются, я могу видеть коллекцию заголовков на свойстве Content HttpResponseMessage, но при доступе к нему через ContentDisposition на заголовках, получить null
Почему это происходит? Скрипач показывает, что заголовки в порядке...
Код:
var responseMessage = await httpClient.GetAsync(uri,
HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(continueOnCapturedContext: false);
Обновление 1
Похоже, что этот класс следует реализации Content-Disposition, описанной в RFC 2616 и не справляется с обновлением реализации Content-Disposition RFC 6266. RFC 2616 определяет filename
значение параметра как строку в кавычках , где обновление RFC 6266 просто указывает, что это должно быть значение.
Грамматика RFC 2616
content-disposition = "Content-Disposition" ":"
disposition-type *( ";" disposition-parm )
disposition-type = "attachment" | disp-extension-token
disposition-parm = filename-parm | disp-extension-parm
filename-parm = "filename" "=" quoted-string
disp-extension-token = token
disp-extension-parm = token "=" ( token | quoted-string )
Грамматика RFC 6266
content-disposition = "Content-Disposition" ":"
disposition-type *( ";" disposition-parm )
disposition-type = "inline" | "attachment" | disp-ext-type
; case-insensitive
disp-ext-type = token
disposition-parm = filename-parm | disp-ext-parm
filename-parm = "filename" "=" value
| "filename*" "=" ext-value
disp-ext-parm = token "=" value
| ext-token "=" ext-value
ext-token = <the characters in token, followed by "*">
Где ext-value = <ext-value, defined in [RFC5987], Section 3.2>
Примеры
Рабочий случай
Неудачный случай
Обновление 2
Открыл билет С MS connect.
Обновление 3
Microsoft признала, что это ошибка и исправит ее.
2 ответа:
Проблема с трейлингом; в заголовке content-disposition
[Fact] public void ParseContentDispositionHeader() { var value = ContentDispositionHeaderValue.Parse("attachment; filename=GeoIP2-City_20140107.tar.gz"); Assert.Equal("GeoIP2-City_20140107.tar.gz",value.FileName); }
Если я добавлю точку с запятой, синтаксический анализ завершится неудачей. Если вы посмотрите на грамматику RFC6266, предполагается, что точка с запятой только предшествует параметру.
Спасибо-найти это определенно помогло мне. Для пользы других, вот мой обходной путь (как, по-видимому, это все еще вещь сегодня???)
Я нахожусь в несколько контролируемой среде, поэтому следующий код предполагает:
- только один заголовок Content-Disposition
- тег имеет следующий формат:
inline; "filename";
Это приведет к сбросу заголовка ContentDisposition ответа, поэтому последующий код работает без проблем:
<!-- language: c# --> if (response.Content.Headers.ContentDisposition == null) { IEnumerable<string> contentDisposition; if (response.Content.Headers.TryGetValues("Content-Disposition", out contentDisposition)) { response.Content.Headers.ContentDisposition = ContentDispositionHeaderValue.Parse(contentDisposition.ToArray()[0].TrimEnd(';').Replace("\"","")); } }