2010-10-31 3 views
1

J'ai un modèle BaseViewModel dont tous mes modèles View héritent.Modèle ASP.NET lié au type de base

public class MagazineViewModel : BaseOutputViewMode 
{ 
    public string TitleOfPublication { get; set; } 
} 

Dans mon contrôleur j'utilise une méthode de fabrication pour donner le Corret Voir modèle retour basé sur une entrée:

// e.g. viewModel contains an instance of MagazineViewModel 
BaseOutputViewModel viewModel = BaseOutputViewModel.GetOutputViewModel(output); 

Lorsque j'utilise TryUpdateModel pour essayer de se lier à un FormCollection que je sais contient une touche « TitleOfPublication », n'a jamais mis son dans mon modèle de vue:

if (!TryUpdateModel(viewModel, form)) 

Je pense que cela est quelque chose à voir avec l'aide de la DefaultModelBinder BaseOutputViewModel pour lier les clés de FormCollection to - il ne contient pas de "TitleOfPublication", le MagazineViewModel dérivé le fait.

J'essaye de rouler mon propre classeur de modèle, pour remplacer le comportement de BindModel de DefaultModelBinder. Son tout câblé correctement et je peux déboguer en tout droit après l'appel TryUpdateModel:

public class TestModelBinder : DefaultModelBinder, IFilteredModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     // Tried the following without success .... 
     // 1. Quick hardcoded test 
     // bindingContext.ModelType = typeof(MagazineViewModel); 
     // 2. Set ModelMetadata, hardcoded test again 
     // bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(MagazineViewModel)); 
     // 3. Replace the entire context 
     // ModelBindingContext context2 = new ModelBindingContext(); 
     // context2.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(MagazineViewModel)); 
     // context2.ModelName = bindingContext.ModelName; 
     // context2.ModelState = bindingContext.ModelState;    
     // context2.ValueProvider = bindingContext.ValueProvider; 
     // bindingContext = context2; 
    } 
} 

Mais je ne sais pas comment travailler avec l'BindingContext? Qu'est-ce qui doit être mis à jour pour que je puisse dire à DefaultModelBinder de lier en utilisant les propriétés dérivées du modèle View? Ou ai-je totalement mal compris cela!

J'ai essayé de remplacer CreateModel - un peu comme le DerivedTypeModelBinder dans MvcContrib, mais je pense que parce que je donne au classeur une instance d'un modèle pour travailler, CreateModel n'est jamais appelé. Réflecteur utilisé sur la DLL Mvc, theres « BindComplexModel » qui appelle CreateModel que si le modèle est nul:

if (model == null) 
{ 
    model = this.CreateModel(controllerContext, bindingContext, modelType); 
} 

Tous les pointeurs greatfully reçu!

Salutations

Répondre

1

OK - enfin au fond de tout ça! En fait il n'y avait rien de mal avec mon classeur de modèle, le problème finalement ramené à deux balises d'entrée qui n'a pas de nom/id:

<input id="" name="" type="text"> 

Le point crucial est ce test dans DefaultModelBinder:

// Simple model = int, string, etc.; determined by calling TypeConverter.CanConvertFrom(typeof(string)) 
// or by seeing if a value in the request exactly matches the name of the model we're binding. 
// Complex type = everything else. 
if (!performedFallback) { 
    ValueProviderResult vpResult = 
      bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
      if (vpResult != null) { 
       return BindSimpleModel(controllerContext, bindingContext, vpResult); 
      } 
     } 

Sans ID/nom, la collection de formulaires a une clé de "", ce qui signifie que GetValue a renvoyé correctement la valeur de ce champ, en continuant à se lier en tant que modèle simple.

Lorsqu'un ID/nom est ajouté, la collection de formulaires ne contient aucune clé de "", (qui est maintenant le nom de mon modèle car nous utilisons TryUpdateModel). Cela signifiait que DefaultModelBinder traitait correctement mon modèle en tant que complexm avec succès les propriétés de liaison dans mon type dérivé!

Cheers

Questions connexes