Refreshing parent view when a partial view’s form is submitted

asp.net-mvc-3partial-viewsrazor

I'm looking into using partial views in MVC3 using Razor, and I get my partial view to render and it works fine.
What I'd like to do, though, is refresh the parent view when the partial view is submitted.

Code in my parent view to render partial view

<div id="mydiv">
@{ Html.RenderAction("Add", "Request"); }
</div>

Action for parent view is simple,

public ActionResult Index()
{
  List<obj> reqs = //some query
  return View(reqs);
}

In my partial view's get action I have:

public ActionResult Add()
{
  AddRequestViewModel vm = new AddRequestViewModel();
  //set some stuff on the VM here
  return PartialView(vm);
}

In the post action called by the partial view, if modelstate isn't valid, return PartialView(vm)

If it is valid, I'd like the parent and partial views to refresh.
I tried RedirectToAction, but this can't be called in an action called by a partial, apparently, and I tried return Index();, but this causes an issue with the code used to render the partial view,

Exception Details: System.InvalidOperationException: The model item passed into the dictionary is of type 'System.Collections.Generic.List'1[DatRequests.Models.ReqRequest]', but this dictionary requires a model item of type 'DatRequests.ViewModels.AddRequestViewModel'.

Any suggestions on how to do this would be appreciated. The purpose of the page is to show a list of elements, and the partial contains a form to add a new element to the list.

Edit: The partial's model is different, as it contains data for selection, which is from a db, which is why I tried RenderAction, but I'm not sure if there are other ways of doing this.

Best Answer

When the partial view is submitted normally you submit it to some controller action. You could either submit it using a normal request or an AJAX request. If you use a normal request you could perform a standard redirect to the Index inside the POST controller action that will handle the form submission. If you use AJAX, you could return a JSON result pointing to the url that you want to redirect:

[HttpPost]
public ActionResult Foo(MyViewModel model)
{
    if (!ModelState.IsValid)
    {
        return PartialView(model);
    }
    return Json(new { url = Url.Action("Index") });
}

and inside your AJAX success callback:

success: function(result) {
    if (result.url) {
        // we have a success
        window.location.href = result.url;
    } else {
        // invalid modelstate => refresh the partial
        $('#mydiv').html(result);
    }
}
Related Topic