Как я могу заставить HttpHeaders.TryGetValues ​​() возвращать несколько значений?

Я использую HttpHeaders.TryGetValues ​​, но я не могу понять, как заставить его возвращать несколько значений.

Вот что я пытаюсь:

using System.Net.Http;

var response = await new HttpClient().GetAsync("https://httpbin.org/response-headers?X-Numbers=0,1,1,2,3,5,8");
var success = response.Headers.TryGetValues("X-Numbers", out var values);
Console.WriteLine($"{success} ({values.Count()}) -> '{values.First()}'");

И вот результат:

True (1) -> '0,1,1,2,3,5,8'

Как обычно, документация очень скудная, и все, что говорится о параметре values, - это

Указанные значения заголовка.

RFC 2616 раздел 4.2 описывает, как HTTP-заголовок может иметь несколько значений (выделено мной ):

Несколько полей заголовка сообщения с одинаковым именем поля МОГУТ присутствовать в сообщении тогда и только тогда, когда все значение поля для этого поля заголовка определено как список, разделенный запятыми [т.е. # (значения)]. ДОЛЖНА быть возможна объединение нескольких полей заголовка в одну пару «имя-поля: значение поля» без изменения семантики сообщения путем добавления каждого последующего значения поля к первому, каждое из которых разделено запятой. Следовательно, порядок, в котором принимаются поля заголовка с одинаковым именем поля, важен для интерпретации значения комбинированного поля, и, таким образом, прокси-сервер НЕ ДОЛЖЕН изменять порядок значений этих полей при пересылке сообщения.

Как мы видим, значения разделены запятыми, поэтому я ожидал, что перечислимое значение будет содержать 7 значений (0, 1, 1, 2, 3, 5 и 8), но вместо этого TryGetValues вернет одно строковое значение.

Могу ли я что-то сделать, чтобы он возвращал несколько значений?


person 0xced    schedule 27.09.2017    source источник
comment
Я не знаю, но вы могли бы подумать, values.SelectMany(v => v.Split(",").Select(s => s.Trim())) просто поймать оба возвращаемых типа и покончить с этим.   -  person itsme86    schedule 28.09.2017
comment
Да, я мог бы, но какой смысл возвращать Enumerable ‹string›, если он всегда возвращает одно значение, и я должен делать эту работу сам?   -  person 0xced    schedule 28.09.2017
comment
В том-то и дело. Я не знаю, так ли это всегда или это зависит от того, как были добавлены заголовки и т. Д. Как вы отметили, документация MSDN определенно отсутствует.   -  person itsme86    schedule 28.09.2017
comment
Ну вот и мой вопрос: могу ли я что-то сделать, чтобы он возвращал несколько значений?   -  person 0xced    schedule 28.09.2017


Ответы (2)


Причина, по которой TryGetValues ​​возвращает перечислимое, заключается в том, что вы можете предоставить несколько заголовков с одним и тем же именем, а также каждый заголовок может иметь несколько значений, разделенных запятыми, как вы упомянули. т.е. "https://httpbin.org/response-headers?X-Numbers=0,1,1,2,3,5,8&X-Numbers=6".

Я согласен, что было бы лучше иметь каждое значение, разделенное запятыми, как одно значение в возвращаемых значениях, перечисляемых, но текущая реализация предполагает, что каждый заголовок может возвращать только одно значение.

person mrtaikandi    schedule 28.09.2017
comment
Ха, несколько заголовков с одинаковым именем, спасибо! - person 0xced; 28.09.2017

Из исходный код, похоже, синтаксический анализатор заголовка Cache-Control в некотором роде уникален:

Заголовок Cache-Control особенный: это заголовок, поддерживающий список значений, но мы представляем этот список как один экземпляр CacheControlHeaderValue. То есть мы устанавливаем SupportsMultipleValues в true, поскольку допустимо наличие нескольких заголовков Cache-Control в сообщении запроса / ответа. Однако после анализа всех заголовков Cache-Control создается только один экземпляр CacheControlHeaderValue (если все заголовки содержат допустимые значения, в противном случае у нас может быть несколько строк, содержащих недопустимые значения).

Запрос на Cache-Control всегда будет возвращать один String, и, насколько я могу судить, нет никакого способа (кроме PR против donet / corefx), чтобы заставить его разделить его за вас. Однако другие заголовки будут вести себя иначе.

Относительно того, почему заголовок Cache-Control обрабатывается таким образом, вам следует спросить реальных разработчиков. Этот файл не претерпел значительных изменений с момента выпуска с открытым исходным кодом.

Для других известных заголовков есть большой список: KnownHeaders.cs. Оттуда вы сможете копаться в любом интересующем вас заголовке.

person Dave Weston    schedule 27.09.2017
comment
Я отредактировал вопрос, чтобы полностью исключить Cache-Control из уравнения, используя вместо этого настраиваемый заголовок X-Numbers. - person 0xced; 28.09.2017