2013-12-22 5 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 Любые идеи?". Кроме того, я думаю, что часть в связующем моле неправильно. Должно быть: bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType (null, modelType); – Botis

+0

Я только создал экземпляр для ExampleType1. Тип экземпляраType = typeof (ExampleType1); В My index action я сказал, что 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. Но я согласен с Ботисом, что, вероятно, есть лучшие подходы. –

ответ

1

Не останавливаясь на причинах, почему вам это нужно (я думаю, что это плохой дизайн, чтобы иметь интерфейс в качестве параметра для методов контроллера). Я думаю, что самым простым решением было бы расширить интерфейс IExample со строковым свойством ImplementedType.

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»); (inter my propertyname в MyModel). ValueProviderResult type = bindingContext.ValueProvider.GetValue ("inter.type"); if (type.AttemptedValue == "ExampleType1") {} . Возможно, я могу сделать невидимую переменную типа. Но это не чистое решение. – user3127359

Смежные вопросы