Sending a form POST HTTP request (Content-Type: application/x-www-form-urlencoded
) to the below controller results into a HTTP 415 Unsupported Media Type response.
public class MyController : Controller
{
[HttpPost]
public async Task<IActionResult> Submit([FromBody] MyModel model)
{
//...
}
}
Form post HTTP headers:
POST /submit HTTP/1.1
Host: example.com:1337
Connection: keep-alive
Content-Length: 219
Pragma: no-cache
Cache-Control: no-cache
Origin: https://example.com:1337
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer: https://example.com:1337/submit
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8,nl;q=0.6
This used to work with ASP.NET MVC 5 on .NET 4.6.
For forms, use the [FromForm]
attribute instead of the [FromBody]
attribute.
The below controller works with ASP.NET Core 1.1:
public class MyController : Controller
{
[HttpPost]
public async Task<IActionResult> Submit([FromForm] MyModel model)
{
//...
}
}
Note: [FromXxx]
is required if your controller is annotated with [ApiController]
. For normal view controllers it can be omitted.
You can use [FromBody]
but you need to set the Content-Type
header of your request to application/json
, i.e.
Content-Type: application/json
First you need to specify in the Headers the Content-Type
, for example, it can be application/json
.
If you set application/json
content type, then you need to send a json.
So in the body
of your request you will send not form-data
, not x-www-for-urlencoded
but a raw
json, for example {"Username": "user", "Password": "pass"}
You can adapt the example to various content types, including what you want to send.
You can use a tool like Postman or curl to play with this.
As addition of good answers, You don't have to use [FromForm]
to get form data in controller. Framework automatically convert form data to model as you wish. You can implement like following.
[HttpPost]
public async Task<IActionResult> Submit(MyModel model)
{
//...
}
[FromQuery]
parameter, but I wasn't specifying the Content-Type as application/json
- adding that in my request, made this work with the [FromQuery] parameter too.
[FromForm]
attribute is only required if the Controller is an ApiController
.
This is my case: it's run Environment: AspNet Core 2.1 Controller:
public class MyController
{
// ...
[HttpPost]
public ViewResult Search([FromForm]MySearchModel searchModel)
{
// ...
return View("Index", viewmodel);
}
}
View:
<form method="post" asp-controller="MyController" asp-action="Search">
<input name="MySearchModelProperty" id="MySearchModelProperty" />
<input type="submit" value="Search" />
</form>
In my case 415 Unsupported Media Types was received since I used new FormData()
and sent it with axios.post(...)
but did not set headers: {content-type: 'multipart/form-data'}
. I also had to do the same on the server side:
[Consumes("multipart/form-data")]
public async Task<IActionResult> FileUpload([FromForm] IFormFile formFile) { ... }
[Consumes("multipart/form-data")]
, without I have null for every parameters :( Why is this so hard to do such a basic thing ..
Follow the below steps:
Add to sending request header Content-Type field: axios.post(`/Order/`, orderId, { headers: {'Content-Type': 'application/json'} }) Every data (simple or complex type) sent with axios should be placed without any extra brackets (axios.post('/Order/', orderId, ...)).
WARNING! There is one exception for string
type - stringify it before send (axios.post('/Order/', JSON.stringify(address), ...)
).
Add method to controller: [HttpPost]
public async Task
With .NET 5
I have a .NET API Controller method that looks like this:
[HttpPost("{rootEntity}/{id}")]
public ActionResult Post(RootEntity rootEntity, int id, [FromBody] string message)
{
...
}
I had this request:
POST /api/Comment/1/1 HTTP/1.1
Host: localhost:12345
Content-Type: text/plain
Content-Length: 4
test
It resulted in the following Status Code response: 415 Unsupported Media Type
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.13",
"title": "Unsupported Media Type",
"status": 415,
"traceId": "00-e7ca54e9f313c24699c3ca4697b9363d-be4719bd10735245-00"
}
I then switched to Content-Type: application/json
like the answer from @BjornBailleul says but got this error instead:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-0549e2c73842c249a93c8dc2f817e250-796e99fc0000224d-00",
"errors": {
"$": [
"'test' is an invalid JSON literal. Expected the literal 'true'. Path: $ | LineNumber: 0 | BytePositionInLine: 1."
]
}
}
Got it working by also encapsulate the string in quotation marks like this: "test"
.
Complete working request:
POST /api/Comment/1/1 HTTP/1.1
Host: localhost:12345
Content-Type: application/json
Content-Length: 6
"test"
https://i.stack.imgur.com/eatjM.png
the problem can because of MVC MW.you must set formatterType in MVC options:
services.AddMvc(options =>
{
options.UseCustomStringModelBinder();
options.AllowEmptyInputInBodyModelBinding = true;
foreach (var formatter in options.InputFormatters)
{
if (formatter.GetType() == typeof(SystemTextJsonInputFormatter))
((SystemTextJsonInputFormatter)formatter).SupportedMediaTypes.Add(
Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse("text/plain"));
}
}).AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
});
Another trap of note is making sure you're not decorating controllers with the Consume Attribute as below:
[Produces("application/json")]
[Consumes("application/json")]
public class MyController : Controller
This will fail with a 415 Unsupported Media Type if the upload is NOT JSON.
A "friend of mine" was recently caught out by this like so:
public class MyFileUploadController : MyCustomController {
}
[Produces("application/json")]
[Consumes("application/json")]
public class MyCustomController : ControllerBase {
}
"HTTP 415 Unsupported Media Type response" stems from Content-Type in header of your request. for example in javascript by axios:
Axios({
method: 'post',
headers: { 'Content-Type': 'application/json'},
url: '/',
data: data, // an object u want to send
}).then(function (response) {
console.log(response);
});
In my case, I received the HTTP 415 Unsupported Media Type response, since I specified the content type to be TEXT and NOT JSON, so simply changing the type solved the issue. Please check the solution in more detail in the following blog post: https://www.howtodevelop.net/article/20/unsupported-media-type-415-in-aspnet-core-web-api
In my case, I had a method in my controller which was requiring an input parameter; unfortunately, the caller (an HttpClient) wasn't passing it. Shame on me.
You must specify Encoding and Content Type, for instance:
var request = new HttpRequestMessage
{
Method = new HttpMethod("POST"),
RequestUri = new Uri(CombineUrl(_baseUrl, _resource))
};
request.Content = new StringContent(contentBody, System.Text.Encoding.UTF8, "application/json");
Success story sharing
application/x-www-form-urlencoded
. Like from a<form>
on a HTML page.application/json
, likeapplication/text
? @BartVerkoeijen any ideas?