2013-12-22 61 views
1

我有一个从接口派生的对象。我想使用显示模板和编辑器模板。显示模板工作得很好。但编辑器模板不能很好地工作。它不理解它说“不能创建一个接口的实例”。 我有一个自定义模型活页夹。但它确实是虚拟的。接口模型绑定 - MVC 4

 protected override object CreateModel(ControllerContext controllerContext,ModelBindingContext bindingContext, Type modelType) 
    {   
     if (modelType.Equals(typeof(IExample))) 
     { 
      Type instantiationType = typeof(ExampleType1); 
      var obj = Activator.CreateInstance(instantiationType); 
      bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, instantiationType); 
      bindingContext.ModelMetadata.Model = obj; 
      return obj; 
     } 

     return base.CreateModel(controllerContext, bindingContext, modelType); 
    } 

我该如何为每个从IExample派生的类做到这一点?有任何想法吗?


[HttpGet] 
    public ActionResult Index() 
    { 
     MyModel model = new MyModel(); 

     model.inter = new ExampleType1(); 

     model.inter.number = 50; 

     return View(model); 
    } 

    [HttpPost]   
    public ActionResult Index(MyModel model) 
    { 
      //*-*-* I want to get it here. 

     return View(); 
    } 

public class MyModel 
{ 

    public IExample inter { get; set; } 

} 


public interface IExample 
{ 
    int number { get; set; } 
} 

public class ExampleType1 : IExample 
{ 
    public int number { get; set; } 
    public string tip1 { get; set; } 
} 
public class ExampleType2 : IExample 
{ 
    public int number { get; set; } 
    public string tip2 { get; set; } 
} 
+0

你说的意思是什么? “我怎么能做到这一点从的​​IExample任何想法派生的每个类?”。另外,我认为moel binder的部分是错误的。应该是:bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null,modelType); – Botis

+0

我只为ExampleType1创建了实例。 类型instantiationType = typeof(ExampleType1);在我的索引操作中,我说IExample是ExampleType1的类型。但我可以说它是ExampleType2。 我也想为ExampleType2创建一个实例。但我想要做到这一点。我可以从IExample派生更多的类。 – user3127359

+0

类似的问题在这里:http://stackoverflow.com/questions/8276627/how-can-i-build-a-custom-model-binder-which-will-return-different-types-of-model。但是我同意Botis的说法,可能有更好的方法。 –

回答

1

没有纠缠于你之所以需要这个(我认为这是一个不好的设计,具有界面为控制器方法的参数)。我认为最简单的解决方案是用字符串属性ImplementedType扩展IExample接口。

public interface IExample 
{ 
    string type {get;} 
    int number { get; set; } 
} 

实现:

public class ExampleType1 : IExample 
{ 
    public string type 
    { get { return "ExampleType1"; } } 
    public int number { get; set; } 
    public string tip1 { get; set; } 
} 

和型号粘结剂:

var type = (string)bindingContext.ValueProvider.GetValue("type"); 
if (type == "ExampleType1") 
{ 
    //create new instance of exampletype1. 
} 
+0

我试过了。但是bindingContext.ValueProvider.GetValue(“type”)返回null。 – user3127359

+0

您应该尝试检查客户端/服务器之间的消息(您可以使用chrome开发人员工具)并检查“type”属性是否实际发送到服务器。如果没有,您可能需要将它添加到您的表单或实际将数据发布到服务器的任何地方。 – Botis

+0

我添加了查看变量'type'。然后当我提交时,我用bindingContext.ValueProvider.GetValue(“inter.type”); (在MyModel中我的属性名称之间)。 ValueProviderResult type = bindingContext.ValueProvider.GetValue(“inter.type”); if(type.AttemptedValue ==“ExampleType1”){} 。也许我可以在视图中创建不可见的“类型”变量。但它不是干净的解决方案。 – user3127359