AspNetCore Accept text/plain as applicatoin/json
We developed a REST API long time ago and recently found that the
released client has a flaw: the HttpRequestMessage is missing
content-type application/json
. In earlier version we
manually deserialize the request json by reading the request body but
now we leverage AspNetCore framework to automatically get the request
structure from the API parameter. However, the legacy client will not
work: HTTP 415 "Unsupported Media Type" error happens.
Therefore, for backward compatibility, we need to make the server
treat all coming requests as application/json
even it is a
plain text (by default).
The legacy client:
msg.Content = new StringContent(JsonConvert.SerializeObject(request));
It should be:
msg.Content = new StringContent(JsonConvert.SerializeObject(request), Encoding.UTF8, "application/json");
First, I try to force modify the request content-type to
applicatoin/json
. However, there is no elegant way to do
this.
Then I explore 3 methods to support text/plain
content-type:
[Consumes()] annotation above Controller class. (not work) This method doesn't work as consumes annotation only restricts the request content-type, but not regard the request as
application/json
. In other words, if you specifytext/plain
in consumes annotation, although the action treat it as a valid type, it will not properly deserialize it to json. 415 error still exists.Reading request body and parsing as json yourself. https://weblog.west-wind.com/posts/2017/Sep/14/Accepting-Raw-Request-Body-Content-in-ASPNET-Core-API-Controllers?Page=2 This method works, but not what we want: we just deprecated manually deserializing object method and resort to leverage AspNetCore framework to do so.
Add
text/plain
to SupportedMediaTypes. (RECOMMENDED) Open your aspnetcoreStartup.cs
, add following snippet toConfigureServices
:
Now the server can handle bothpublic void ConfigureServices(IServiceCollection services) { ... services.AddMvc(config => { foreach (var formatter in config.InputFormatters) { if (formatter.GetType() == typeof(JsonInputFormatter)) { ((JsonInputFormatter) formatter).SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/plain")); } } }); ... }
text/plain
andapplication/json
, treating request body as json format.