Web API 415: Unsupported Media Type

Nithin 1 Reputation point
2022-07-08T19:04:50.14+00:00

How can I support two content types for an endpoint

  • application/x-www-form-urlencoded
  • application/json
ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,599 questions
0 comments No comments
{count} votes

4 answers

Sort by: Most helpful
  1. Zhi Lv - MSFT 32,436 Reputation points Microsoft Vendor
    2022-07-12T10:49:05.42+00:00

    Hi @Nithin ,

    Web API 415: Unsupported Media Type

    219816-image.png

    In Asp.Net Core API application, if not add the binding source attributes like [FromBody] or [FromForm] (refer to the above code), on the Post method when bind the complex object, it will find the action parameter value from the request body(the Content-Type: application/json), if you transfer the parameter value from the request Form (application/x-www-form-urlencoded), it will show the 415 error.

    How can I support two content types for an endpoint

    • application/x-www-form-urlencoded
    • application/json

    To let one endpoint to support two content types, you can try to use custom model binding. In the custom model binder method, you can check the request content type, then based on the content type to get the parameter value from the request Form or request body, then create the object instance and return to the API method.

    For example, create an asp.net 6 API application:

    1. Create a Student class: 219720-image.png
    2. Add the API controller as below: 219770-image.png
    3. Add the custom model binder: [Note] need to install the Newtonsoft.Json package. 219874-image.png
    4. Register the custom model binder in the program.cs file. 219749-image.png [Note] We need to allow Synchronous IO to get the value from the request body.

    You can view the source code, it contains all above code: 219796-sourcecode.txt

    Then the result as below:

    219818-1.gif


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,
    Dillion

    2 people found this answer helpful.

  2. Jaliya Udagedara 2,821 Reputation points MVP
    2022-07-08T19:48:09.163+00:00
    • To use application/x-www-form-urlencoded, [ApiController]
      [Route("[controller]")]
      public class ToDosController : ControllerBase
      {
      [HttpPost]
      public IActionResult Post([FromForm] ToDo toDo)
      {
      return Ok();
      }
      } public record class ToDo(int Id, string Title);

    cURL,

       curl --location --request POST 'http://localhost:5000/Todos' \  
       \--header 'Content-Type: application/x-www-form-urlencoded' \  
       \--data-urlencode 'id=1' \  
       \--data-urlencode 'title=ToDo 1'  
    
    • To use application/json, [ApiController]
      [Route("[controller]")]
      public class ToDosController : ControllerBase
      {
      [HttpPost]
      public IActionResult Post(ToDo toDo) // you can be explicit if you want to, something like Post([FromBody] ToDo toDo), default is application/json
      {
      return Ok();
      }
      } public record class ToDo(int Id, string Title);

    cURL

       curl --location --request POST 'http://localhost:5000/Todos' \  
       \--header 'Content-Type: application/json' \  
       \--data-raw '{  
           "id": 1,  
           "title": "ToDo 1"  
       }'  
    

  3. Bruce (SqlWork.com) 66,061 Reputation points
    2022-07-08T22:22:53.36+00:00

    if you use:

    public IActionResult Post([FromBody] ToDo toDo)     
    

    you are telling the binder to use an input formatter. the builtin are text and json InputFormatters. You can optionally add additional formatters like Xml via .AddXmlSerializerFormatters()

    there currently isn't a form url encoded input formatter.

    if you use:

    public IActionResult Post([FromForm] ToDo toDo)     
    

    then the binder uses a media formatter (much slower) to access the form data

    if you use:

    public IActionResult Post(ToDo toDo)     
     
    

    the binder will look at the content-type and pick either FromForm or FromBody processing

    0 comments No comments

  4. Qing Guo - MSFT 896 Reputation points Microsoft Vendor
    2022-07-11T11:00:26.813+00:00

    Hi @Nithin ,

    In Postman , the multipart/form-data request type allows you to specify a content type for each individual part.

    By default, the content type of each part is not visible. You need to enable this by clicking the three dots and enabling Content Type.

    219515-1.png

    Below is an example , you can refer to it.

    Values Controller:

        [Route("api/[controller]")]  
        [ApiController]  
        public class ValuesController : ControllerBase  
        {  
            [HttpPost]  
            public IActionResult Post([FromForm] ToDo toDo)  
            {  
                return Ok();  
            }        
        }  
    

    result:

    219809-3.png

    219459-5.gif


    If the answer is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Regards,
    Qing Guo


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.