5

I've got a page in an app I'm building. The page contains a few bits and pieces, then a partial view that loads a different view depending on what's selected from a dropdown. Each of the options from the dropdown has a different view associated with it, and each view has its own fields and model.

Whatever the view is that loads, I'm performing the same action - I'm serializing the model and storing the XML in a database. This is always the case, and there is no unique processing based on the views/models (other than the fact that the fields are different). All models inherit from the same base class for serialization purposes.

I wanted to be able to do something like:

public ActionResult SubmitPartialView<T>(T model)
{
   BaseClass baseClassModel = (BaseClass)(object)model;
   // serialize and save to database
}

But MVC doesn't allow this - "cannot call action on controller because the action is a generic method".

If I try passing the BaseClass in as a parameter itself, it only contains the properties of the base class and therefore none of the model's properties.

Is there no other option other than to create a separate action for every single view that can submit, and make each one call a separate method that handles the logic?

jardantuan
  • 505
  • 1
  • 4
  • 14
  • 1
    Create class that would contains all Models (ModelsContainer), and then just receive Model Container without generics. Might also help https://stackoverflow.com/questions/20009031/how-to-use-asp-net-mvc-generic-controller-to-populate-right-model – Vladimir Jun 09 '17 at 11:39
  • Can you show us the code fragment that calls that method? – Adam Benson Jun 09 '17 at 13:34
  • Or simple do it without the DefaultModelBinder, and bind the Request in the Action for this case. – Christian Gollhardt Jun 09 '17 at 21:33

1 Answers1

3

I see this question is a little old, but if it helps anyone - I was doing some reading with dynamic models and MVC, saw this and it led me to think of a possible solution. Not sure why you would want to have dynamic models. But the great thing with MVC is, you can!

So;

    [HttpPost]
    public ActionResult SubmitPartial([DynamicModelBinder] dynamic model)
    {
        // Our model.ToString() serialises it from the baseModel class
       var serialisedString = model.ToString();
        // do something .. echo it back for demo
       return Content(serialisedString);
    }

And the model binder is something like this;

public class DynamicModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var currentModel = controllerContext.HttpContext.Request.Form["CurrentModel"];
        if (currentModel == "CompanyModel")
        {
            Type customModel = typeof(CompanyModel);
            bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, customModel);
        }

        if (currentModel == "UserModel")
        {
            Type customModel = typeof(UserModel);
            bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, customModel);
        }

        return base.BindModel(controllerContext, bindingContext);
    }
}

hth

wortho
  • 31
  • 2