问题
I post $('#myForm').serializeArray()
to an ASP.NET MVC (2.0) action.
serialized array looks as follows:
filters[0][name] : gemcolor
filters[0][value] : Yellow
filters[1][name] : gemcolor
filters[1][value] : Green
filters[2][name] : jcOnly
filters[2][value] : true
someOtherData : abc
I want to have that consumed in:
public ActionResult GetData(Filter filter)
class Filter {
string someOtherData;
bool jcOnly;
List<string> gemcolor;
}
I can just dig through FormCollection
, but I am looking for a more elegant solution (I suspect it will involve a custom model binder).
回答1:
This won't work because the default model binder doesn't expect the data to be formatted like this. Simply use .serialize() instead of serializeArray()
. Example:
$.ajax({
url: '/foo',
type: 'post',
data: $('#myForm').serialize(),
success: function(result) {
alert('ok');
}
});
or simplify your life by using the excellent jquery form plugin which allows you to AJAXify existing HTML forms in an elegant manner:
$(function() {
$('#myForm').ajaxForm(function(result) {
alert('ok');
});
});
UPDATE:
After the explanation in your comment here's how you could proceed:
You could use the plugin from this answer which transforms the form elements into an object understandable by the default model binder and could be aggregated with some other information:
$.fn.serializeObject = function()
{
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name]) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
and then simply:
data: { filters: $('#myForm').serializeObject(), someOtherData: 'foo bar' }
回答2:
I know this is old, but how about something like this - this is what I use generically on my pages to submit via ajax:
$(function () {
@*-- PostAll--*@
$(".postAll").click(function () {
var container = $(this).closest(".postGroup");
var p = {};
container.find("input[type='text'], input[type='radio']:checked, input:checkbox:checked, textarea").each(function (i, e) {
p[$(e).attr("name")] = $(e).val();
});
container.find('select').each(function (i, e) {
p[$(e).attr("name")] = $(e).find('option:checked').val();
});
$.post($(this).data("url"), p, function (data, status) {
//Do Some Notification
})
});
});
I tend to have html structure as:
- Div containing all the form elements
- A button with within the div
- button with a url attribute with the url
Something like this:
<div class="postGroup">
<div class="row">
<div class="col-md-2 col-md-offset-3">
<input type="text" name="myText" />
</div>
<div class="col-md-2">
<input type="radio" name="myRad" value="A1" />
<input type="radio" name="myRad" value="A2" />
<input type="radio" name="myRadTwo" value="A3" />
<input type="radio" name="myRadTwo" value="A4" />
</div>
<div class="col-md-2">
<input type="checkbox" name="mycheck" value="B1" />
<input type="checkbox" name="mycheck" value="B2" />
<input type="checkbox" name="mycheckTwo" value="B3" />
<input type="checkbox" name="mycheckTwo" value="B4" />
</div>
<div class="col-md-2">
<select name="mySelect">
<option value="S1">Select 1</option>
<option value="S2">Select 2</option>
<option value="S3">Select 3</option>
<option value="S4">Select 4</option>
</select>
<select name="mySelectTwo">
<option value="R1">Select 1</option>
<option value="R2">Select 2</option>
<option value="R3">Select 3</option>
<option value="R4">Select 4</option>
</select>
</div>
</div>
<button class="postAll" data-url="/MyEndpoint">click</button>
</div>
Then you can have a normal model to capture what you need. Not sure if this is the best way or anything but I use this a of times.
来源:https://stackoverflow.com/questions/4807218/consume-jquery-serializearray-in-asp-net-mvc