Reputation: 8655
In an ASP.NET MVC3 application, I'm trying to use jQuery to make an asynchronous post to an action.
The following JSON object is being passed as data...
{
categoryId: "21"
content: "asdf"
reference: "asdf"
tags: [
{id: 1, name: "asdf", status: 1},
{id: 2, name: "asdf", status: 1},
{id: 3, name: "asdf", status: 1}
]
}
The method signature I have to receive the request is
[HttpPost]
public ActionResult Create(String reference, Int32? categoryId, String content, IEnumerable<TagDTO> tags)
with TagDTO is being defined as:
public class TagDTO
{
public String name { get; set; }
public Int32 id { get; set; }
public Int32 status { get; set; }
}
I should mention that before I introduced the array of objects to the JSON object and to the signature of the action method, this was working perfectly. And the Post is still successfully reaching the action, only the data in the IEnumerable is not coming through correctly. It will give me the correct number of objects in the IEnumerable, but they are all initialized to default values. (id=0, name=null, status=0)
I'm not sure what I'm doing wrong here. I hope this makes sense. I'm hoping someone can show me the proper way to pass data to an MVC action in this manner.
Thanks
Here is the javascript function I'm using to perform my ajax call...
function saveResource() {
var tagAssignments = [];
for (var x = 0; x < $('.tag-assignment').length; x++) {
var tag = $($('.tag-assignment')[x]);
tagAssignments.push({
name: tag.find('.tag-name').html().toString(),
id: parseInt(tag.find('.tag-id').html()),
status: parseInt(tag.find('.tag-status').html())
});
}
$.ajax({
url: '/Resources/Create',
dataType: 'json',
type: 'POST',
success: function (data) {
if (data.status == 'Success') {
forwardToDefaultPage();
} else {
alert(data.status);
}
},
data: {
reference: $('#txt-resource-reference').val(),
categoryId: $('#ddl-category').val(),
content: $('#txt-resource-content').val(),
tags: tagAssignments
}
});
}
Upvotes: 1
Views: 2590
Reputation: 1038710
I'd would recommend you using view models and send JSON request.
So a view model:
public class CreateViewModel
{
public string Reference { get; set; }
public int? CategoryId { get; set; }
public string Content { get; set; }
public IEnumerable<TagDTO> Tags { get; set; }
}
action:
[HttpPost]
public ActionResult Create(CreateViewModel model)
{
...
}
AJAX request:
// TODO: build this object dynamically as you are currently doing
// but always start with hardcoded values like this to test first
var data = {
categoryId: '21',
content: 'asdf',
reference: 'asdf',
tags: [
{ id: 1, name: 'asdf', status: 1 },
{ id: 2, name: 'asdf', status: 1 },
{ id: 3, name: 'asdf', status: 1 }
]
};
$.ajax({
url: '@Url.Action("create", "resources")',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ model: data }),
success: function(result) {
...
}
});
The JSON.stringify
method used here is built into modern browsers. If you need to support legacy browsers you could add the json2.js script to your page.
Upvotes: 3
Reputation: 3645
A couple of things to try.
Look at changing to your ajax call as shown below.
function saveResource() {
var tagAssignments = [];
for (var x = 0; x < $('.tag-assignment').length; x++) {
var tag = $($('.tag-assignment')[x]);
tagAssignments.push({
name: tag.find('.tag-name').html().toString(),
id: parseInt(tag.find('.tag-id').html()),
status: parseInt(tag.find('.tag-status').html())
});
}
$.ajax({
url: '<%: Url.Action("Create", "Resources")',
dataType: 'json',
type: 'POST',
success: function (data) {
if (data.status == 'Success') {
forwardToDefaultPage();
} else {
alert(data.status);
}
},
data: {
reference: $('#txt-resource-reference').val(),
categoryId: $('#ddl-category').val(),
content: $('#txt-resource-content').val(),
tags: JSON.stringify(connect)
}
});
}
and change your IEnumerable to IList in your action
[HttpPost]
public ActionResult Create(String reference, Int32? categoryId, String content, IEnumerable<TagDTO> tags)
Upvotes: 0