Je crée quelques classeurs personnalisés pour les types complexes dans mon modèle. Mon modèle est composé d'objets qui ont leurs propres liants séparés. Je veux que l'objet de base fasse son sale boulot, puis remplisse l'objet complexe qu'il encapsule en passant au routage ModelBinder standard. Comment puis-je faire cela?Comment puis-je appeler UpdateModel à partir d'un ModelBinder personnalisé? (MVC)
Pour l'illustration j'ai créé un exemple très simple.
Dites que mon modèle contient ces objets.
public class Person
{
public string Name {get; set;}
public PhoneNumber PhoneNumber {get; set;}
}
public class PhoneNumber
{
public string AreaCode {get; set;}
public string LocalNumber {get; set;}
}
Et j'ai les classeurs suivants pour chacun de ces modèles. Non que PersonBinder doit remplir le PhoneNumber mais ne souhaite pas dupliquer le code dans le classeur PhoneNumber. Comment délègue-t-il au routage Binder standard?
public class PersonBinder: IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
Person person = new Person();
person.Name = bindingContext.ValueProvider.GetValue(String.Format("{0}.{1}", bindingContext.ModelName, "Name")).AttemptedValue
// This is where I'd like to have the PhoneNumber object use binding from another customer ModelBinder.
// Of course the bindingContext.ModelName should be updated to its current value + "PhoneNumber"
person.PhoneNumber = ???; // I don't want to explicitly call the PhoneNumberBinder it should go through standard Binding routing. (ie. ModelBinders.Binders[typeof(PhoneNumber)] = new PhoneNumberBinder();)
return person;
}
}
public class PhoneNumberBinder: IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
PhoneNumber phoneNumber = new PhoneNumber();
phoneNumber.AreaCode = bindingContext.ValueProvider.GetValue(String.Format("{0}.{1}", bindingContext.ModelName, "AreaCode")).AttemptedValue
phoneNumber.LocalNumber = bindingContext.ValueProvider.GetValue(String.Format("{0}.{1}", bindingContext.ModelName, "LocalNumber")).AttemptedValue
return phoneNumber;
}
}
Et bien sûr, j'ai enregistré mes ModelBinders dans le fichier Global.asax.cs.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
ModelBinders.Binders[typeof(Person)] = new PersonBinder();
ModelBinders.Binders[typeof(PhoneNumber)] = new PhoneNumberBinder();
}
Merci,
Justin
Merci pour la suggestion, mais je ne pense pas que l'AutoMapper est l'outil pour moi. On dirait une solution de contournement. Je suis sûr que les liants devraient supporter cette fonctionnalité nativement. – Justin