(To clarify, I have read other questions and their answers and tried all solutions, but none of them solved the issue)
I'm debugging locally a code that I'll deploy to Windows Azure Cloud Services. It's an ASP.NET Web API application that was working just a few days ago, but not anymore.
I have a controller with both GET and POST handlers. The GET handler works fine and returns the desired result, however the POST handler is not able to get the parameters from the POST body request. This handler was working just fine a few builds ago (~2 days ago), however it's not working now. Here are the details:
First, both GET and POST handlers:
public class PlayerController : ApiController
{
[HttpGet]
public HttpResponseMessage Information(string userID)
{
// Works fine!
}
[HttpPost]
public HttpResponseMessage Insert(PlayerEntry entry)
{
// All values from entry are null or 0!
}
}
This is the PlayerEntry
model:
public class PlayerEntry
{
public string userID;
public string userName;
public int userProgress;
}
This is the POST request being made (taken from Fiddler):
POST http://127.0.0.1/api/player/insert HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 80
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
userID=20&userName=Test&userProgress=9
And this is the Debug Output in the server:
iisexpress.exe Information: 0 : Request, Method=POST, Url=http://127.0.0.1:81/api/player/insert, Message='http://127.0.0.1:81/api/player/insert'
iisexpress.exe Information: 0 : Message='Player', Operation=DefaultHttpControllerSelector.SelectController
iisexpress.exe Information: 0 : Message='MvcWebRole1.Controllers.PlayerController', Operation=DefaultHttpControllerActivator.Create
iisexpress.exe Information: 0 : Message='MvcWebRole1.Controllers.PlayerController', Operation=HttpControllerDescriptor.CreateController
iisexpress.exe Information: 0 : Message='Selected action 'Insert(PlayerEntry entry)'', Operation=ApiControllerActionSelector.SelectAction
iisexpress.exe Information: 0 : Message='Value read='MvcWebRole1.Models.PlayerEntry'', Operation=JQueryMvcFormUrlEncodedFormatter.ReadFromStreamAsync
iisexpress.exe Information: 0 : Message='Parameter 'entry' bound to the value 'MvcWebRole1.Models.PlayerEntry'', Operation=FormatterParameterBinding.ExecuteBindingAsync
iisexpress.exe Information: 0 : Message='Model state is valid. Values: entry=MvcWebRole1.Models.PlayerEntry', Operation=HttpActionBinding.ExecuteBindingAsync
iisexpress.exe Information: 0 : Message='Action returned 'StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StringContent, Headers:
{
Content-Type: text/plain; charset=utf-8
}'', Operation=ReflectedHttpActionDescriptor.ExecuteAsync
iisexpress.exe Information: 0 : Operation=ApiControllerActionInvoker.InvokeActionAsync, Status=200 (OK)
iisexpress.exe Information: 0 : Operation=PlayerController.ExecuteAsync, Status=200 (OK)
iisexpress.exe Information: 0 : Response, Status=200 (OK), Method=POST, Url=http://127.0.0.1:81/api/player/insert, Message='Content-type='text/plain; charset=utf-8', content-length=0'
iisexpress.exe Information: 0 : Operation=PlayerController.Dispose
So far, these are the things I've tried that didn't change anything:
[FromBody]
before PlayerEntry entry
in the Insert()
functionHowever, when I simply remove the PlayerEntry
model and get the POST parameters from the URL (and send the parameters through the URL. I did that only as a test), I can get all the parameters without problems.
What could be causing the issue here? I did not change any code in the handlers as far as I remember (only code that runs internally and connects to an SQL Server and returns results), and all of a sudden I got this problem.
I believe the default model binder does not bind to fields, only properties with a public setter. Try changing your fields to properties:
public class PlayerEntry
{
public string userID { get; set; }
public string userName { get; set; }
public int userProgress { get; set; }
}
For what it's worth, I got sick of trying to get it to serialize correctly and did it myself.
My data is a javascript array of strings which posts like "value=thing1,thing2,thing3" and I was able to serialize it using the following:
$('<form>', {
"id": "dynamicForm",
"html": '<input type="hidden" id="val" name="val" value="' + $scope.items + '" />',
"action": '/api/Example/',
"method": "post"
}).appendTo(document.body).submit();
Then on the server side:
[HttpPost]
[Route("")]
public HttpResponseMessage Post()
{
var values = HttpContext.Current.Server.UrlDecode(Request.Content.ReadAsStringAsync().Result).Replace("val=","").Split(',');
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With