Search code examples
asp.net-mvcexceptionmodelaction-filteronexception

Any way to recover model passed to POST action when inside OnException(ExceptionContext filterContext)?


Situation is this:

I can't find a way of getting the viewModel that was passed to the POST action method.

[HttpPost]
public ActionResult Edit(SomeCoolModel viewModel)
{
    // Some Exception happens here during the action execution...
}

Inside the overridable OnException for the controller:

protected override void OnException(ExceptionContext filterContext)
{
    ...

    filterContext.Result = new ViewResult
    {
        ViewName = filterContext.RouteData.Values["action"].ToString(),
        TempData = filterContext.Controller.TempData,
        ViewData = filterContext.Controller.ViewData
    };
}

When debugging the code filterContext.Controller.ViewData is null since the exception occurred while the code was executing and no view was returned.

Anyways I see that filterContext.Controller.ViewData.ModelState is filled and has all the values that I need but I don't have the full ViewData => viewModel object available. :(

I want to return the same View with the posted data/ViewModel back to the user in a central point. Hope you get my drift.

Is there any other path I can follow to achieve the objective?


Solution

  • You could create a custom model binder that inherits from DefaultModelBinder and assign the model to TempData:

    public class MyCustomerBinder : DefaultModelBinder
    {
        protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            base.OnModelUpdated(controllerContext, bindingContext);
    
            controllerContext.Controller.TempData["model"] = bindingContext.Model;
        }
    }
    

    and register it in Global.asax:

    ModelBinders.Binders.DefaultBinder = new MyCustomerBinder();
    

    then access it:

    protected override void OnException(ExceptionContext filterContext)
    {
        var model = filterContext.Controller.TempData["model"];
    
        ...
    }