Monday, May 20, 2024
Homepage · c#
 Popular · Latest · Hot · Upcoming
90
rated 0 times [  96] [ 6]  / answers: 1 / hits: 34610  / 11 Years ago, thu, february 13, 2014, 12:00:00

I'm trying to tack on some additional data a POST request sent to my server. Originally, I was sending just several forms worth of information:



$.ajax({
url: 'SaveAllDetails',
type: 'POST',
data: $('form').serialize(),
dataType: 'json'
});


and the MVC Controller method:



[HttpPost]
public ActionResult SaveAllDetails([Bind(Prefix = order)]ExistingOrderDetailsModel existingOrderDetailsModel,
[Bind(Prefix = task)]ExistingTaskDetailsModel existingTaskDetailsModel, [Bind(Prefix = device)]DeviceDetailsModel deviceDetailsModel)
{
....
}


This works great. MVC's model binder is able to correctly de-serialize the URL-encoded string.



Now, requirements have changed. I need to send an additional array of data along with my three forms. This array of data is not held within a form and does not have a binding prefix. I need to do this all in the same Controller method because all validation needs to be performed inside of a single transaction.



So, I've now got:



var subcomponentsGridRows = JSON.stringify(subcomponentsDetailsView.getAllGridData());
var existingOrderDetailsFormData = $('form#existingOrderDetailsForm').serialize();
var existingTaskDetailsFormData = $('form#existingTaskDetailsForm').serialize();
var deviceDetailsFormData = $('form#existingDeviceDetailsForm').serialize()

$.ajax({
url: 'SaveAllDetails',
type: 'POST',
data: {
existingOrderDetailsModel: existingOrderDetailsFormData,
existingTaskDetailsModel: existingTaskDetailsFormData,
deviceDetailsModel: deviceDetailsFormData,
subcomponentsGridRows: subcomponentsGridRows
},
dataType: 'json'
});


This doesn't work for at least one reason. Each form is represented as a URL-encoded string. subcomponentsGridRows is a JSON structure. The MVC model binder isn't capable of deciphering both types of information in one go as far as I can tell.



What's a good way to go about tackling this problem?


More From » c#

 Answers
9

You might find the following plugin useful.



Here's how it might be useful to you. Let's start by cleaning your controller action by defining a view model:



public class MyViewModel
{
public ExistingOrderDetailsModel Order { get; set; }
public ExistingTaskDetailsModel Task { get; set; }
public DeviceDetailsModel Device { get; set; }

public AdditionalRowsViewModel[] AdditionalRows { get; set; }
}


In this example the AdditionalRowsViewModel will obviously hold the additional information you are trying to pass to the controller action.



And then your controller action will become:



[HttpPost]
public ActionResult SaveAllDetails(MyViewModel model)
{
....
}


OK, this step was absolutely necessary, it's just that when I see a controller action taking more than 1 parameter I simply define a view model.



And finally let's adapt our AJAX call:



$.ajax({
url: 'SaveAllDetails',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({
order: $('form#existingOrderDetailsForm').serializeObject(),
task: $('form#existingTaskDetailsForm').serializeObject(),
device: $('form#existingDeviceDetailsForm').serializeObject(),
additionalRows: subcomponentsDetailsView.getAllGridData()
}),
success: function(result) {
// do something with the result of the AJAX call here
}
});


Things to notice:




  1. Get rid of this dataType: 'json' parameter in your AJAX request. You are using ASP.NET MVC and hopefully you are returning a Jsonresult from your controller action which is successfully setting the Content-Type response header to the correct value. jQuery is intelligent enough to use the value of this response header and pre-process the result variable that will be passed to the success callback of your AJAX request. So in this case you will already get a javascript object

  2. Since you are sending JSON to the server in your AJAX request you need to properly specify the contentType: application/json parameter. Otherwise how do you expect that ASP.NET MVC will know that the client is sending JSON and apply the correct model binder? By the way the default Content-Type request header that jQuery will send is application/x-www-form-urlencoded, so if you are sending JSON payload in your POST request that would be a conflict and violation of the protocol.


[#72535] Wednesday, February 12, 2014, 11 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
trentb

Total Points: 261
Total Questions: 101
Total Answers: 90

Location: French Southern and Antarctic Lands
Member since Fri, Jan 6, 2023
1 Year ago
;