我正在为模型中的复杂类型创建一些自定义粘合剂。我的模型由具有自己独立的粘合剂的对象组成。我希望基本对象进行肮脏的工作,然后通过传递到标准模型框路由来填充其封装的复杂对象。我该怎么做呢?

出于插图目的,我创建了一个非常简单的示例。

说我的模型包含这些对象。

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;}
}

我对每个模型都有以下粘合剂。并不是说PersonBinder需要填充声载体,而是不想复制Phonenumber粘合剂中的代码。如何委派回到星德粘合剂路由?

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;
    }
}

当然,我已经在global.asax.cs文件中注册了modelbinders。

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterRoutes(RouteTable.Routes);

    ModelBinders.Binders[typeof(Person)] = new PersonBinder();
    ModelBinders.Binders[typeof(PhoneNumber)] = new PhoneNumberBinder();
}

谢谢,

贾斯汀

有帮助吗?

解决方案

好吧,我设法提出了一个解决方案。请随时评论其有效性。

public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
     Person person = new Person();
     person.Name = bindingContext.ValueProvider.GetValue("Name").AttemptedValue

     if (bindingContext.ModelName == String.Empty)
     {
         bindingContext.ModelName = "PhoneNumber";
     }
     else
     {
         bindingContext.ModelName = bindingContext.ModelName + ".PhoneNumber";
     }

     PhoneNumber phoneNumber = new PhoneNumber();
     bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => phoneNumber, phoneNumber.GetType());

     IModelBinder binder = ModelBinders.Binders[typeof(PhoneNumber)];
     if (binder == null)
     {
          binder = ModelBinders.Binders.DefaultBinder;
     }

     person.PhoneNumber = binder.BindModel(controllerContext, bindingContext) as PhoneNumber;

     return person;                         
}

这是我所做的事情的摘要。

  1. 使用全球可访问的modelbinders.binders Collection查找模型迎合器(如果未注册,则为默认值的后备)
  2. 为我绑定到的模型创建ModelMetadataProvider。
  3. 将BindingContext的模型名属性设置为我要填充的模型属性(“ Phonenumber”)。

其他提示

您可以用户自动应用程序并处理动作中的复杂模型构建,而不是编写活页夹。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top