Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC - Generic Actions

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?

like image 306
jardantuan Avatar asked Oct 30 '22 06:10

jardantuan


1 Answers

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

like image 170
wortho Avatar answered Nov 17 '22 13:11

wortho