Runtime: CheckMediaTypeFormat throws exception for valid Content Types

Created on 18 Feb 2017  路  9Comments  路  Source: dotnet/runtime

MediaTypeHeaderValue.CheckMediaTypeFormat(String mediaType, String parameterName) (https://github.com/dotnet/corefx/blob/master/src/System.Net.Http/src/System/Net/Http/Headers/MediaTypeHeaderValue.cs#L254-L266) throws exception for value "text/html; charset=ISO-8859-4" which is used as an example in the w3 RFC 2616.

But, moreover why is this checked anyways? For example, what if I'd like to include invalid header values in my acceptance tests to ensure the server is responding appropriately? How should I set this up in my tests if I can't do this? This creates a limitation around which scenarios can be reproduced in code.

request.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html; charset=ISO-8859-4");

From what I can tell this method disallows ANY media type parameters which doesn't make much sense to me.

area-System.Net.Http enhancement

Most helpful comment

I do think that more work needs to be done to bring this into compliance with RFC 2616, as it does say in the docs that it is compliant.

Given that the actual example in the docs

An example of a media-type would be "text/plain; charset=iso-8859-5.

introduces this error - i.e., if I do new MediaTypeHeaderValue("text/plain; charset=iso-8859-5"); I get a FormatException, I'd classify this as a bug, not an enhancement.

All 9 comments

dotnet/corefx#16292 would allow media type parameters, but again I think the solution should be to remove this check or provide an alternative mechanism for creating requests which may be invalid.

or provide an alternative mechanism for creating requests which may be invalid.

For example, what if I'd like to include invalid header values in my acceptance tests to ensure the server is responding appropriately? How should I set this up in my tests if I can't do this? This creates a limitation around which scenarios can be reproduced in code. In terms of the strongly typed properties such as ContentType, we don't want to allow invalid formats. The whole point of the strongly typed properties is to produce only valid formats.

You can add headers that have invalid formats to them by using other APIs to add to the header collections for either HttpRequestMessage.Headers or HttpRequestMessage.Content.Headers.

Try using the TryAddWithoutValidation method:
https://msdn.microsoft.com/en-us/library/hh875107(v=vs.118).aspx

That should allow you to add the header with the "invalid" format. It will then get sent on the wire as-is.

@davidsh given that there is a workaround, do we still want to keep it as enhancement for future?
What exactly should we enhance?

PowerShell repo we have related Issue and we find ourselves in a quandary because left "as is" is bad, skip the check is bad too and make own "full standard" verification is impossible.
If CheckMediaTypeFormat reject a standard valid formats this is very strange. Base methods must conform to the standards and expectations of users.
InFrom MSDN docs MediaTypeHeaderValue Class:

Represents a media-type as defined in the RFC 2616.

It throws if you pass in the entire content type, but you can set the CharSet like so:

request.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
request.Content.Headers.ContentType.CharSet = "ISO-8859-4";

But, I'm not sure what the path would be for specifying media type parameters other than charset. Such as (from the w3c example):

Accept: audio/*; q=0.2, audio/basic

I do think that more work needs to be done to bring this into compliance with RFC 2616, as it does say in the docs that it is compliant.

Given that the actual example in the docs

An example of a media-type would be "text/plain; charset=iso-8859-5.

introduces this error - i.e., if I do new MediaTypeHeaderValue("text/plain; charset=iso-8859-5"); I get a FormatException, I'd classify this as a bug, not an enhancement.

I got around this issue by creating an instance of StringContent and adding the Content-Type header like this

var content = new StringContent( ... );

content.Headers.Remove("Content-Type");
content.Headers.TryAddWithoutValidation("Content-Type", "text/html; charset=ISO-8859-4");

var response = await client.PostAsync(uri, content);

Here's a way to do it without calling functions that have WithoutValidation in the name (note I'm adding both charset and type):

var content = StringContent("{ \"Foo\": \"Bar\" }", Encoding.UTF8);
var mediaType = new MediaTypeHeaderValue("application/atom+xml") {CharSet = "utf-8" } ;
mediaType.Parameters.Add(new NameValueHeaderValue("type", "entry"));
content.Headers.ContentType = mediaType;

How is this still not fixed?
@mustakimali your workaround was a life saver

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jamesqo picture jamesqo  路  3Comments

iCodeWebApps picture iCodeWebApps  路  3Comments

aggieben picture aggieben  路  3Comments

GitAntoinee picture GitAntoinee  路  3Comments

chunseoklee picture chunseoklee  路  3Comments