I'm trying to check if an Accept
header includes a MIME type like this:
public static bool AcceptsView(this HttpRequest request) => request.Headers.Accept.Contains("text/html");
However even when the Accept header is Accept: text/html, text/plain, application/json
it returns false
. What am I doing wrong?
The Microsoft.AspNetCore.Http.HttpRequest
defines a property called Headers
which is an IHeaderDictionary
. This interface defines an Accept
property which is a StringValues
. This type basically a string collection which implements a lots of interfaces, like IEnumerable<string>
.
Whenever you call Contains
on the Accept
that checks whether the provided string is present in the collection. In your case this property contains a single element. Not one element per acceptable mime type.
So, you have a collection with a single element text/html, text/plain, application/json
and you are checking whether it has an element with text/html
. That's the reason why it always returns false.
So, you should check whether is there any item inside the StringValues
collection which contains the provided string:
request.Headers.Accept.Any(x => x.Contains("text/html"))
Another way to perform this check is to use the GetTypedHeaders
. This will return a RequestHeaders
instance. Its Accept property is not a StringValues
rather a IList<MediaTypeHeaderValue>
. So, here you have one MediaTypeHeaderValue
per acceptable mime type.
The MediaTypeHeaderValue
has a property called MediaType
. Its type is a StringSegment
which does have a Value
property.
request.GetTypedHeaders().Accept.Any(x => x.MediaType.Value == "text/html")
You can also avoid hard coding text/html
. The System.Net.Mime
namespaces defines several classes like MediaTypeNames
or MediaTypeNames.Text
. The latter one has a constant called Html
which contains the text/html
request.GetTypedHeaders().Accept.Any(x => x.MediaType == MediaTypeNames.Text.Html)