【问题标题】:How come my model binder isn't finding types within a class?为什么我的模型绑定器没有在类中找到类型?
【发布时间】:2011-10-16 15:46:42
【问题描述】:

我有以下课程:

public class Truck {
      public Wheel Wheel { get; set; } 
}

public class Wheel {
      public int Number { get; set; }
}

我注册了以下模型绑定器:

ModelBinders.Binders.Add(typeof(Wheel), new WheelModelBinder());

还有:

public class WheelModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        throw new NotImplementedException();
    }
}

如果我通过:

public ActionResult(Wheel wheel) { ... }

模型绑定器被命中并引发异常。如果我通过了

public ActionResult(Truck Truck) { ... }

模型绑定器没有被击中。

在我的应用程序中,每次 Wheel 进入时(无论它是否嵌套在另一种类型中),我都希望模型绑定器将其拾取并操作 Wheel 上的属性。完成此任务的最佳方法是什么?

编辑:使用 EditorFor() 正确绑定了我,但我无法任意编辑属性。使用上面的例子:

public class WheelModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var valueProviderResult = bindingContext.ValueProvider.GetValue("Wheel.Number");
        return null;
    }
}

这将正确获取轮子属性。但是,我可能有一个新的、更复杂的对象:

public class Cars {
    public class Truck { get; set; }
}

这破坏了ValueProvider,我需要这样做,...GetValue("Truck.Wheel.Number") 我在滥用 ModelBinder 吗?有没有更好的方法来实现我的结果(假设我的结果是进行外部查找以确保属性 Number 有效,如果不是,请将其设置为其他值)。

【问题讨论】:

    标签: c# asp.net-mvc asp.net-mvc-3 model-binding


    【解决方案1】:

    只需使用型号名称:

    var valueProviderResult = bindingContext
        .ValueProvider
        .GetValue(bindingContext.ModelName + ".Number");
    

    现在,无论对象图有多深,您的模型绑定器都可以正常工作。

    【讨论】:

      【解决方案2】:

      实际上,您的 ModelBinder 和模型将按定义工作。

      阻碍你的组件是视图。如果您使用以下内容:

      @model MyApplication5.Models.Truck 
      @{
          ViewBag.Title = "Index";
          Layout = "~/Views/Shared/_Layout.cshtml";
      }
      
      <h2>Truck</h2>
      
      @using (Html.BeginForm())
      {
          @Html.EditorFor(m => m.Wheel)
          <button type="submit">Submit</button>
      }
      

      然后视图将生成正确命名的元素,供您的自定义 ModelBinder 使用。

      但是,在这种情况下,您不需要自定义 ModelBinder,因为只要遵循 MVC 的约定,DefaultModelBinder 就会处理您的嵌套模型。通常,自定义 ModelBinder 用于 (1) DefaultModelBinder 无法使用的复杂自定义类型或模型,或 (2) 您使用自定义命名约定的地方。

      【讨论】:

      • 见上面我的 cmets。如果你认为这超出了问题的范围,我会开一个新的,并奖励你这个问题的分数。
      • 问题的范围肯定已经改变了。但是,为了解决上面的 cmets,您正在尝试使用 ModelBinder 进行模型验证。这绝对不是推荐的方法。使用 DataAnnotations 和内置验证方法来确定轮数是否有效会更好地为您服务。
      • 由于范围变化,我给了你最佳答案,但我给了你和 Darin 积分。
      【解决方案3】:

      这似乎是因为您甚至没有要绑定的 Truck 对象(尽管这实际上可能不是一个问题),而且我正在收集您的观点并没有以正确的格式写出来。为了绑定集合,您必须符合 Phil Haacks 博客中介绍的特定命名格式

      http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

      您的元素是否符合此命名约定?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-09-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-15
        相关资源
        最近更新 更多