2010-04-15 1 views
2

У меня есть сценарий, где мне нужно привязываться к интерфейсу - для создания правильного типа у меня есть настраиваемое связующее устройство, которое знает, как создать правильный конкретный тип (которые могут отличаться).ModelBinders, сложные вложенные типы и интерфейсы

Однако созданный тип никогда не заполнял поля. Я знаю, что мне не хватает чего-то ослепительно простого здесь, но может ли кто-нибудь сказать мне, почему или, по крайней мере, что мне нужно сделать, чтобы модельное связующее продолжало работать и связывать свойства?

public class ProductModelBinder : DefaultModelBinder 
{ 
    override public object BindModel (ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     if (bindingContext.ModelType == typeof (IProduct)) 
     { 
      var content = GetProduct (bindingContext); 

      return content; 
     } 

     var result = base.BindModel (controllerContext, bindingContext); 

     return result; 
    } 

    IProduct GetProduct (ModelBindingContext bindingContext) 
    { 
     var idProvider = bindingContext.ValueProvider.GetValue ("Id"); 
     var id = (Guid)idProvider.ConvertTo (typeof (Guid)); 

     var repository = RepositoryFactory.GetRepository<IProductRepository>(); 
     var product = repository.Get (id); 

     return product; 
    } 
} 

Модель в моем случае это сложный тип, который имеет свойство IProduct, и это те ценности, мне нужно заполняли

Модель:.

[ProductBinder] 
public class Edit : IProductModel 
{ 
    public Guid Id { get; set; } 
    public byte[] Version { get; set; } 

    public IProduct Product { get; set; } 
} 

ответ

0

ModelBinder работает рекурсивно так, что вам нужно выполнить привязку пользовательской модели, переопределить метод onCreate и BindModel.

protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) 
{ 
// get actual type of a model you want to create here 
    return Activator.CreateInstance(type); 
} 

public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
{ 
    // here our CreateModel method will be called 
    var model = base.BindModel(controllerContext, bindingContext); 
    // we will get actual metadata for type we created in the previous line 
    var metadataForItem = ModelMetadataProviders.Current.GetMetadataForType(() => model, model.GetType()); 
    // and then we need to create another binding context and start model binding once again for created object 
    var newModelBindingContext = new ModelBindingContext 
     { 
      ModelName = bindingContext.ModelName, 
      ModelMetadata = metadataForItem, 
      ModelState = bindingContext.ModelState, 
      PropertyFilter = bindingContext.PropertyFilter, 
      ValueProvider = bindingContext.ValueProvider 
     }; 
     return base.BindModel(controllerContext, newModelBindingContext); 

}

Надежда, что помогает.