HttpResponseMessage.Content.Headers ContentDisposition имеет значение null
При загрузке файла с помощью HttpClient я загружаю сначала заголовки, а затем содержимое. Когда загружаются заголовки, я вижу коллекцию заголовков в свойстве Content HttpResponseMessage, но при доступе к ней через ContentDisposition в заголовках, получите null
![screenshot]()
Почему это происходит? Fiddler показывает, что заголовки в порядке...
код:
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>
Примеры
Рабочий случай
![Working case]()
Неудачный случай
![Failing case]()
Обновление 2
Открыл билет с подключением MS.
Обновление 3
Microsoft признала, что это ошибка и исправит ее.
Ответы
Ответ 1
Проблема заключается в завершении; в заголовке содержимого
[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, то только двоеточие должно предшествовать параметру.
Ответ 2
Спасибо, что это определенно помогло мне. В интересах других, вот мое обходное решение (по-видимому, это еще вещь сегодня???)
Я в некоторой степени контролируемой среде, поэтому следующий код предполагает:
- Только один заголовок Content-Disposition
- Тег находится в формате:
inline; "filename";
Это будет reset ответ заголовка 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("\"",""));
}
}