Pass ViewModel with jQuery post?
I'm trying to do a post with jQuery in an MVC app开发者_如何学运维lication, according to this SO answer here: Can jQuery do a POST of a ViewModel to a Controller in ASP.NET MVC?
The difference is I am using it to delete an item in a dynamic view (never mind the fact that I'm posting a delete directly, this is a closed site by authorization, and I will use jQuery to confirm, I just don't want the user to have to go to a new page). And I therefore need to be able to send both the id and the ViewModel (the ViewModel to save any added items before deleting any). I'm not particularly happy with the solution by and large, but at this point I just need to get it to work!
So I tried to figure out how to send both the id and the ViewModel according to the SO post above, but I can't figure out how to get the ViewModel in with the named parameters. This doesn't work:
$(".delete").click(function () {
$.ajax({
type: "POST",
url: deleteurl,
data: ({id : $(this).closest('tr').find('td:first').text(),vm: $('form').serialize()}),
cache: false,
success: function (html) {
$("#rows").html(html);
}
});
return false;
});
Here's the POST action method:
[HttpPost]
public ActionResult Delete(int id, LanguageViewModel vm)
{
for (int i = 0; i < vm.Languages.Count; i++)
{
var language = _repository.GetLanguage(vm.Languages[i].Id); //This is the key, get the original program object to update
UpdateModel(language, "Languages[" + i + "]");
}
_repository.Save();
//Delete code will go here
return RedirectToAction("Edit", "Languages", new { id = id });
//return View();
}
Again, it doesn't work, it doesn't even get to the action method in the debugger. If I remove the int id parameter from the action method it actually gets there, but with vm = null. I have no clue what to do, so any help will be greatly appreciated!
EDIT: Sorry, the return value should be as changed now, not return View().
UPDATE:
With a little help from Darin it's almost working:
[HttpPost]
public ActionResult Delete(LanguageViewModel vm, FormCollection collection)
{
for (int i = 0; i < vm.Languages.Count; i++)
{
var language = _repository.GetLanguage(vm.Languages[i].Id); //This is the key, get the original program object to update
UpdateModel(language, "Languages[" + i + "]");
}
_repository.Save();
int id = Int32.Parse(collection["HiddenId"]);
Language languageToDelete = _repository.GetLanguage(id);
_repository.Delete(languageToDelete);
vm.Languages.Remove(vm.Languages.SingleOrDefault(l => l.Id == id));
_repository.Save();
return PartialView("LanguageList", vm);
}
But I have changed to return a PartialView (which was what I was supposed to do from the beginning since that is what the jQuery does - load a div with the results). But the problem is, after returning this Partial View from the action method and loading it in the div with jQuery, the $(".delete").click jQuery function doesn't work anymore...
Any ideas why?
You could try including a hidden field inside your form that will hold the id:
<input type="hidden" name="id" id="hiddenid" value="" />
and then:
$('.delete').click(function () {
var id = $(this).closest('tr').find('td:first').text();
$('#hiddenid').val(id);
$.ajax({
type: 'POST',
url: deleteurl,
data: $('form').serialize(),
cache: false,
success: function (html) {
$('#rows').html(html);
}
});
return false;
});
which could be simplified to:
$('.delete').click(function () {
var id = $(this).closest('tr').find('td:first').text();
$('#hiddenid').val(id);
$('#rows').load(deleteurl, $('form').serialize());
return false;
});
Have you tried appending the id to the deleteurl before posting?
Something like this has worked for me:
deleturl = deleteurl + "/" + id;
hth,
\ ^ / i l l
How about passing the FormCollection as the second argument instead of viewmodel. Then you can do a TryUpdateModel on your language object before saving and/or deleting.
精彩评论