Folks, I've attempted this on MVC4 and MVC5.
I need to pass an object with a few properties and a collection from the client to the controller.
I've defined the model in C# as:
public enum RequestMode { ReadOnly = 0, Edit = 1}
public class DataRequest
{
public int ProjectId { get; set; }
public RequestMode Mode { get; set; }
public List<PageRequest> PageRequests { get; set; }
public DataRequest()
{
PageRequests = new List<PageRequest>();
}
}
public class PageRequest
{
public int Id { get; set; }
public int PageCurrent { get; set; }
public int RowCountPerPage { get; set; }
}
The MVC Controller is defined as (just using it to set a breakpoint to check the request values):
[HttpPost]
public JsonResult Test(DataRequest request)
{
return new JsonResult();
}
The Index.cshtml client contains the ajax call:
<script type="text/javascript">
var RequestMode = { ReadOnly: 0, Edit: 1 };
var dataRequest = { ProjectId: 17, Mode: RequestMode.Edit, PageRequests: new Array() };
var pageRequest = { TableId: 3165, PageCurrent: 4, RowCountPerPage: 30 };
dataRequest.PageRequests.push(pageRequest);
$(document).ready(function () {
$.ajax({
data: dataRequest,
type: 'POST',
cache: false,
url: '/Home/Test',
success: function (data) {
},
fail: function (data) {
}
});
});
</script>
I start debugging, the page loads and my breakpoint in the controller Test method gets hit.
In the debugger, the request object shows up as: Mode: Edit PageRequests: Count = 1 ProjectId: 17
When I expand the PageRequests collection property, I see: {Mvc5WebTest.Controllers.PageRequest} Id: 0 PageCurrent: 0 RowsPerPage: 0
I would expect the PageRequest object to be populated with the values I've set (i.e. 3165, 4, 30)
Using Fiddler, I see that the complete DataRequest object is getting turned into Json correctly, but it seems that the MVC controller can't turn it back into the C# object.
As a workaround, I can modify the ajax call on the client to var cdr = JSON.stringify(dataRequest);
$.ajax({
dataType: 'json',
type: 'GET',
data: { jsonRequest: cdr },
...
And then in the controller
[HttpGet]
public ActionResult Test(string jsonRequest)
{
var request = JsonConvert.DeserializeObject<DataRequest>(jsonRequest);
return new JsonResult();
}
This works, but I'd rather not pass the data as a string.
Can anyone shed some light as to what is going on and what I need to do to get the collection populated?
You have to specify that you're sending JSON over because the default content type is string:
Because you're posting JSON data, you have to convert the object to string by using
JSON.stringify
and declare thecontentType: "application/json; charset=utf-8"
I also noticed that in C# code, you defined
PageRequest
asWhile in js,
There is a conflict between
Id
in C# andTableId
in js. You will have to use one or the other.