Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.net core 2 rejects request with 415 when I set Accept to text/csv

When i POST a request to my .net core 2 mvc backend it returns json data.

I want to optionally change the headers as so , which i will then return a csv file of the data for download

'Accept': 'text/csv',
'Content-Type': `text/csv; charset=utf-8`

I set the controller base class with this Produces filter

[Produces("application/json", "text/csv")]

But those headers always cause .net to return 415 Unsupported Media Type

The controller action looks like this

[HttpPost] 
public async Task<IActionResult> Post([FromBody] PostArgs args)
like image 293
masteroleary Avatar asked Sep 06 '25 03:09

masteroleary


2 Answers

You source of problem is Content-Type: text/csv; charset=utf-8 header.

[FromBody] forces MVC middleware to use the input formatter for model binding (I am talking about PostArgs model). And by default, ASP.NET Core registers only one, JSON input formatter. Cause you set Content-Type, middleware cannot use that default formatter (as Content-Type header says that data in request body should be processed as CSV, not JSON) and so it throws 415 Unsupported Media Type error.


... I want to optionally change the headers as so , which i will then return a csv file of the data for download

Actually, it looks like you understand in wrong way what Content-Type header does:

In requests, (such as POST or PUT), the client tells the server what type of data is actually sent.

In other words, you only need to specify the Accept header, cause

The Accept request HTTP header advertises which content types, expressed as MIME types, the client is able to understand. Using content negotiation, the server then selects one of the proposals.

And it is the server then, who uses a Content-Type header in responses to tell the client what the content type of the returned content (in response) actually is.

like image 122
Set Avatar answered Sep 09 '25 02:09

Set


To return csv data, you return a ContentResult rather than a JsonResult object. This allows you to define the Content-Type:

return new ContentResult("csv-data", "text/csv", 200);

If you want to return a physical file you could return a FileResult object.


By default, the Accepts header isn't enforced. You can enforce it via configuration:

services.AddMvc(config =>
{
    config.RespectBrowserAcceptHeader = true;
}); 

In order to accept additional formats, you'll also need to add InputFormatters:

services.AddMvc(config =>
{
    config.RespectBrowserAcceptHeader = true;
    config.InputFormatters.Add(new TextInputFormatter())
    config.OutputFormatters.Add(new StringOutputFormatter());
});
like image 44
Marc LaFleur Avatar answered Sep 09 '25 01:09

Marc LaFleur