代码之家  ›  专栏  ›  技术社区  ›  David

MVC复杂模型绑定

  •  0
  • David  · 技术社区  · 15 年前

    我想对包含对象列表的表单进行复杂验证。

    我的表单包含一个列表,比如说,我的对象。MyObject由一个双数量和一个MyDate组成,它只是一个日期时间的包装器。

    public class MyObject
    {
        public MyDate Date { get; set; } //MyDate is wrapper around DateTime
        public double Price { get; set; }
    }
    

    形式…

    <input type="text" name="myList[0].Date" value="05/11/2009" />
    <input type="text" name="myList[0].Price" value="100,000,000" />
    
    <input type="text" name="myList[1].Date" value="05/11/2009" />
    <input type="text" name="myList[1].Price" value="2.23" />
    

    这是我的行动

    public ActionResult Index(IList<MyObject> myList)
    {
       //stuff
    }
    

    我希望允许用户输入100000000作为价格,并允许自定义模型活页夹去掉“,”以便它可以转换为双精度。同样,我需要将2009年11月5日转换为mydate对象。我想创建一个myObjectModelBinder,但不知道从那里该怎么做。

    ModelBinders.Binders[typeof(MyObject)] = new MyObjectModelBinder();
    

    感谢您的帮助。

    2 回复  |  直到 15 年前
        1
  •  2
  •   Darin Dimitrov    15 年前

    下面是自定义模型绑定器的示例实现:

    public class MyObjectModelBinder : DefaultModelBinder
    {
        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            // call the base method and let it bind whatever properties it can
            var myObject = (MyObject)base.BindModel(controllerContext, bindingContext);
            var prefix = bindingContext.ModelName;
            if (bindingContext.ValueProvider.ContainsKey(prefix + ".Price"))
            {
                string priceStr = bindingContext.ValueProvider[prefix + ".Price"].AttemptedValue;
                // priceStr = 100,000,000 or whatever the user entered
                // TODO: Perform transformations on priceStr so that parsing works
                // Note: Be carefull with cultures
                double price;
                if (double.TryParse(priceStr, out price))
                {
                    myObject.Price = price;
                }
            }
    
            if (bindingContext.ValueProvider.ContainsKey(prefix + ".Date"))
            {
                string dateStr = bindingContext.ValueProvider[prefix + ".Date"].AttemptedValue;
                myObject.Date = new MyDate();
                // TODO: Perform transformations on dateStr and set the values 
                // of myObject.Date properties
            }
    
            return myObject;
        }
    }
    
        2
  •  0
  •   Jarrett Meyer    15 年前

    你一定走对了。当我这样做的时候,我做了一个中间视图模型,它将price作为一个字符串,因为有逗号。然后,我将视图模型(或表示模型)转换为控制器模型。控制器模型有一个非常简单的构造函数,它接受一个视图模型,并且可以 Convert.ToDecimal("12,345,678.90") 价格价值。