Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accept x-www-form-urlencoded in Web API .NET Core

I have a .NET Core Web API that is returning a 415 Unsupported Media Error when I try to post some data to it that includes some json. Here's part of what is returned in the Chrome Debugger:

Request URL:http://localhost:51608/api/trackAllInOne/set Request Method:POST Status Code:415 Unsupported Media Type Accept:text/javascript, text/html, application/xml, text/xml, */* Content-Type:application/x-www-form-urlencoded  action:finish currentSco:CSharp-SSLA:__How_It_Works_SCO data:{"status":"incomplete","score":""} activityId:13 studentId:1 timestamp:1519864867900 

I think this has to do with my controller not accepting application/x-www-form-urlencoded data - but I'm not sure. I've tried decorating my controler with Consumes but that does not seem to work.

[HttpPost] [Route("api/trackAllInOne/set")] [Consumes("application/x-www-form-urlencoded")] public IActionResult Post([FromBody] PlayerPackage playerPackage) { etc..} 

Any help greatly appreciated.

The following code worked fine in .NET 4.6.1 and I am able to capture and process the posts shown above.

[ResponseType(typeof(PlayerPackage))] public async Task<IHttpActionResult> PostLearningRecord(PlayerPackage playerPackage) {     if (!ModelState.IsValid)     {         return BadRequest(ModelState);     }      var id = Convert.ToInt32(playerPackage.ActivityId);     var learningRecord = await _context.LearningRecords.FindAsync(id);     if (learningRecord == null)         return NotFound(); etc... 
like image 477
Roddy Balkan Avatar asked Mar 01 '18 01:03

Roddy Balkan


2 Answers

Try using [FromForm] instead of [FromBody].

public IActionResult Post([FromForm] PlayerPackage playerPackage) 
  • FromBody > Bind from JSON

  • FromForm > Bind from Form parameters

You can also remove [FromBody] altogether and trial it then. Because you are expecting form-urlencoded should tell it to bind to object.

like image 175
Aeseir Avatar answered Sep 21 '22 09:09

Aeseir


For PlayerPackage, the request should send a PlayerPackage Json Object, based on your description, you could not control the request which is posted from other place.

For the request, its type is application/x-www-form-urlencoded, it will send data with {"status":"incomplete","score":""} in string Format instead of Json object. If you want to accept {"status":"incomplete","score":""}, I suggest you change the method like below, and then conver the string to Object by Newtonsoft.Json

[HttpPost] [Route("~/api/trackAllInOne/set")] [Consumes("application/x-www-form-urlencoded")] public IActionResult Post([FromForm] string data) {     PlayerPackage playerPackage = JsonConvert.DeserializeObject<PlayerPackage>(data);     return Json(data); } 
like image 29
Edward Avatar answered Sep 19 '22 09:09

Edward