我有一种情况,我有8个对象都从一个对象继承。出于某些目的,这些对象必须是他们自己的类,但在初始创建时,它们没有任何不同。
它们不能作为基础对象创建,必须将它们作为自己的对象添加到数据库中。这是不容谈判的。
为此创建16个控制器操作和8个视图似乎很愚蠢。我只需知道添加了哪种类型,从来没有任何不同。所以基本上我需要做以下......
abstract class Base {
Guid Id { get; set; }
string Name { get; set; }
string Description { get; set; }
}
class Alpha : Base { // }
class Beta : Base { // }
class Sigma : Base { // }
class Delta : Base { // }
class ObjectViewModel {
string Name { get; set; }
string Description { get; set; }
}
ActionResult Create(){
return View();
}
[HttpPost]
ActionResult Create(ObjectViewModel model) {
// determine which type needs to be created
Factory.Create(model); // the factory will create the right object based on the type
repository.Add(factoryCreatedObject);
// ...
}
看起来很简单,但它不起作用。我试过在ViewModel上放一个System.Type
属性 - 它只是不起作用。我唯一能够开始工作的是使用一个巨大的switch
语句,但这似乎是一种糟糕的方法。
有没有办法在没有过多冗余的情况下完成这项工作?
答案 0 :(得分:1)
如何创建自定义模型绑定器:
public class BaseModelBinder : DefaultModelBinder
{
private Type _type;
protected override ICustomTypeDescriptor GetTypeDescriptor(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
return TypeDescriptor.GetProvider(_type).GetTypeDescriptor(_type);
}
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
var result = bindingContext.ValueProvider.GetValue("type");
if (result == null)
{
throw new Exception("please provide a valid type parameter");
}
_type = Type.GetType(result.AttemptedValue);
if (_type == null || !typeof(Base).IsAssignableFrom(_type))
{
throw new Exception("please provide a valid type parameter");
}
return Activator.CreateInstance(_type);
}
}
您将在Application_Start
注册:
ModelBinders.Binders.Add(typeof(Base), new BaseModelBinder());
现在您可以执行以下控制器操作:
public ActionResult Foo(Base model)
{
...
}
现在,当您调用此操作时,只需传递一个额外的type
参数,指示您要创建的具体实例。例如:
http://localhost:1203/?type=MvcApplication1.Models.Alpha&Id=21EC2020-3AEA-1069-A2DD-08002B30309D&Name=Test&Description=Somedescription&AlphaProp=alpha