You can try Controller.UpdateModel or Controller.TryUpdateModel method:
[HttpPost]
public ActionResult SaveStatement(User currentUser, FormCollection statement, string ViewModelName)
{
...
object ViewModel = Activator.CreateInstance(type);
if (TryUpdateModel(viewModel))
{
// save the ViewModel
}
return View(ViewModelName, ViewModel);
}
However I would suggest you to create a custom ModelBinder, as it is its responsibility to create and populate model properties.
I can show you a simple example how you can achieve this:
Base ViewModel
public abstract class StatementViewModel
{
public abstract StatementType StatementType { get; }
...
}
public enum StatementType
{
Relief,
RequestForSalary,
...
}
ViewModels
public class RequestForSalaryVM : StatementViewModel
{
public override StatementType StatementType
{
get { return StatementType.RequestForSalary; }
}
...
}
public class ReliefVM : StatementViewModel
{
public override StatementType StatementType
{
get { return StatementType.Relief; }
}
...
}
ModelBinder
public class StatementModelBinder : DefaultModelBinder
{
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
var statementTypeParameter = bindingContext.ValueProvider.GetValue("StatementType");
if (statementTypeParameter == null)
throw new InvalidOperationException("StatementType is not specified");
StatementType statementType;
if (!Enum.TryParse(statementTypeParameter.AttemptedValue, true, out statementType))
throw new InvalidOperationException("Incorrect StatementType"); // not sure about the type of exception
var model = SomeFactoryHelper.GetStatementByType(statementType); // returns an actual model by StatementType parameter
// this could be a simple switch statement
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, model.GetType());
bindingContext.ModelMetadata.Model = model;
return model;
}
}
After that register the model binder in the Global.asax
:
ModelBinders.Binders.Add(typeof(StatementViewModel), new StatementModelBinder());
Controller
[HttpPost]
public ActionResult Index(StatementViewModel viewModel)
{
if (ModelState.IsValid)
{
// save the model
}
return View(viewModel);
}