How would you pass objects with MVC and jQuery AJAX?
I am finally experimenting and trying to learn MVC after years of asp.net.
I am used to using asp.net AJAX PageMethods where you can pass an object that automagically gets parsed to whatever type the parameter is in that method.Javascript:
PageMethods.AddPerson({First:"John",Last:"Doe"});
Code-Behind:
[WebMethod]
public stat开发者_如何学运维ic Result AddPerson(Person objPerson)
{
return Person.Save();
}
How would do this using MVC and jQuery?
Did just have to send strings and parse the json to object?That depends on how complex your form data is going to be. Let's use a jQuery example:
$.ajax({
url: '\Persons\AddPerson', // PersonsController, AddPerson Action
data: { First: "John", Last: "Doe" },
type: 'POST',
success: function(data, status)
{
alert('Method called successfully!');
}
});
So we post two pieces of data. If the Person class has two properties called 'First' and 'Last', then the default ASP.NET MVC Model Binder should have no problems putting this form data into those properties (everything else will be defaulted).
Of course, you could always make a custom model binder for the Person type, and then you can take whatever form values you want and put them into any property at all, or call some other kind of logic.
I have a post that covers AJAX calls to ASP.NET MVC action methods. It covers the following combinations:
- HTTP GET, POST
- jQuery methods $.get, $.getJSON, $.post
- Sending parameters to the action methods
- Returning parameters (strings and JSON) from the action methods
- Posting form data
- Loading a MVC partial view via AJAX
AJAX calls to ASP.NET MVC action methods using jQuery
When you POST a form via ajax to an action method on your controller, the ModelBinder architecture kicks in to parse the posted form values into business objects for you. You can leverage modelbinding in a few different ways.
public ActionResult MyAction(MyObject obj)
{
}
In the above example, the modelbinder implicitly tries to create a MyObject
from the information it received in the request.
public ActionResult MyAction(FormCollection stuff)
{
MyObject obj = new MyObject();
TryUpdateModel(obj);
}
Here we are explicitly trying to bind the posted form data to an object that we created. The ModelBinder will try to match the posted values to the properties of the object.
In either of these cases, you can query the ModelState
object to see if there were any errors that occurred during translation of the posted values to the object.
For an introduction to model binding, see here.
For advanced modelbinding to lists and dictionaries, see Phil Haack's post.
You could do something like this:
var person = {};
person["First"] = $("#FirstName").val();
person["Last"] = $("#LastName").val();
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/Admin/AddPerson",
data: JSON.stringify(person),
dataType: "json",
success: function(result) {
},
error: function(result) {
}
});
and then on your admin controller:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddRelease(Person p)
{
// Code to add person
}
The JSON.stringify method is available from here. You could also use a model rather than the Person object as a parameter that way you could handle all of your validation.
I guess I am a cheater and do the following:
$("#ProgressDialog").dialog({
autoOpen: false,
draggable: false,
modal: true,
resizable: false,
title: "Loading",
closeOnEscape: false//,
// open: function () { $(".ui-dialog-titlebar-close").hide(); } // Hide close button
});
$("form").live("submit", function (event) {
event.preventDefault();
var form = $(this);
$("#ProgressDialog").dialog("open");
$.ajax({
url: form.attr('action'),
type: "POST",
data: form.serialize(),//USE THIS to autoserialize!
success: function (data) {
$("#dialog").dialog({height:0});
},
error: function (jqXhr, textStatus, errorThrown) {
alert("Error '" + jqXhr.status + "' (textStatus: '" + textStatus + "', errorThrown: '" + errorThrown + "')");
},
complete: function () {
$("#ProgressDialog").dialog("close");
}
});
});
});
<div id="ProgressDialog" style="text-align: center; padding: 50px;">
<img src="@Url.Content("~/Content/ajax-loader.gif")" width="128" height="15" alt="Loading" />
</div>
精彩评论