Я пытаюсь проверить, содержит ли заголовок Accept
тип MIME, например:
public static bool AcceptsView(this HttpRequest request) => request.Headers.Accept.Contains("text/html");
Однако даже если заголовок Accept равен Accept: text/html, text/plain, application/json
, он возвращает false
. Что я делаю не так?
Это список, а не строка. Попробуйте сделать...Accept.Contains(new MediaTypeWithQualityHeaderValue("text/html"))
@MakePeaceGreatAgain Да, я отладил, и значение равно "text/html, text/plain, application/json"
, поэтому я в замешательстве. Разве это не должен быть массив значений, содержащий типы MIME?
@DA Я получаю эту ошибку: «CS1929 'StringValues' не содержит определения для 'Contains' и лучшая перегрузка метода расширения 'MemoryExtensions.Contains<MediaTypeWithQualityHeaderValue>(ReadOnlySpan<MediaTypeWithQualityHeaderValue>, MediaTypeWithQualityHeaderValue)' требует получатель типа «System.ReadOnlySpan<System.Net.Http.Headers.MediaTypeWithQualityHeaderValue>»
Я думаю, что это массив, однако отладчик показывает его строковое представление, то есть "Accept: text/html, text/plain, application/json"
. В любом случае, вам просто нужно использовать request.Headers.Accept.Any(x => x.ToString() == "text/html");
Я это уже пробовал, разницы нет
О каком HttpRequest
классе речь? Один внутри System.Web
, другой внутри Microsoft.AspNetCore.Http
пространства имен и т. д.
Microsoft.AspNetCore.Http
, ControllerBase.Request
Microsoft.AspNetCore.Http.HttpRequest
определяет свойство Headers , которое представляет собой IHeaderDictionary . Этот интерфейс определяет свойство Accept, которое является StringValues . По сути, этот тип представляет собой коллекцию строк, реализующую множество интерфейсов, например IEnumerable<string>
.
Всякий раз, когда вы вызываете Contains
на Accept
, который проверяет, присутствует ли предоставленная строка в коллекции. В вашем случае это свойство содержит один элемент. Ни одного элемента для каждого допустимого типа MIME.
Итак, у вас есть коллекция с одним элементом text/html, text/plain, application/json
и вы проверяете, есть ли в ней элемент с text/html
. Вот почему он всегда возвращает false.
Итак, вам следует проверить, есть ли в коллекции StringValues
какой-либо элемент, содержащий указанную строку:
request.Headers.Accept.Any(x => x.Contains("text/html"))
Другой способ выполнить эту проверку — использовать GetTypedHeaders . Это вернет экземпляр RequestHeaders . Его свойство Accept — это не StringValues
, а IList<MediaTypeHeaderValue>
. Итак, здесь у вас есть один MediaTypeHeaderValue
на каждый допустимый тип пантомимы.
MediaTypeHeaderValue имеет свойство MediaType . Его тип — StringSegment, у которого есть свойство Value
.
request.GetTypedHeaders().Accept.Any(x => x.MediaType.Value == "text/html")
Вы также можете избежать жесткого кодирования text/html
. Пространства имен System.Net.Mime
определяют несколько классов, таких как MediaTypeNames или MediaTypeNames.Text . Последний имеет константу Html, которая содержит text/html
request.GetTypedHeaders().Accept.Any(x => x.MediaType == MediaTypeNames.Text.Html)
Вы отлаживали и видели, что такое
Accept
на самом деле? Полагаю, это коллекция из одного элемента с"Accept: text/html, text/plain, application/json"
. Однако ваш код проверяет коллекцию из трех элементов со значениями"text/html"
,"text/plain"
и"application/json"
.