为什么我的模型绑定器找不到类中的类型?
我有以下类:
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;
}
}
这将正确获取wheel属性。但是,我可能有一个新的、更复杂的对象:
public class Cars {
public class Truck { get; set; }
}
这会破坏 ValueProvider
,我需要这样做,... GetValue("Truck.Wheel.Number")
我是否滥用 ModelBinder?有没有更好的方法来实现我的结果(假设我的结果是进行外部查找以确保属性 Number
有效,如果无效,请将其设置为其他内容)。
I have the following classes:
public class Truck {
public Wheel Wheel { get; set; }
}
public class Wheel {
public int Number { get; set; }
}
And I registered the following model binder:
ModelBinders.Binders.Add(typeof(Wheel), new WheelModelBinder());
And:
public class WheelModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
throw new NotImplementedException();
}
}
If I pass in:
public ActionResult(Wheel wheel) { ... }
The model binder gets hit and throws an exception. If I pass in
public ActionResult(Truck Truck) { ... }
The model binder doesn't get hit.
In my application, every time Wheel goes in (whether or not it is nested within another type), I want the model binder to pick it up and manipulate the properties on wheel. What's the best way to accomplish this?
Edit: Using EditorFor() correctly binds me, but I'm unable to arbitrarily edit the property. Using the above example:
public class WheelModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var valueProviderResult = bindingContext.ValueProvider.GetValue("Wheel.Number");
return null;
}
}
This will correctly get the wheel property. However, I might have a new, more complex object:
public class Cars {
public class Truck { get; set; }
}
This breaks the ValueProvider
and I will need to do, ... GetValue("Truck.Wheel.Number")
Am I abusing ModelBinder? Is there a better way to achieve my result (assume my result is to do an external lookup to make sure property Number
is valid and if not, set it to something else).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
只需使用模型名称:
现在无论对象图有多深,您的模型绑定器都将正常工作。
Simply use the model name:
Now no matter how deep the object graph is your model binder will work correctly.
实际上,您的 ModelBinder 和模型将按定义工作。
使你绊倒的组件是视图。如果您使用以下内容:
那么视图将生成正确命名的元素以供您的自定义 ModelBinder 使用。
但是,在这种情况下,您不需要自定义 ModelBinder,因为只要遵循 MVC 的约定,DefaultModelBinder 就会处理您的嵌套模型。通常,自定义 ModelBinder 适用于 (1) DefaultModelBinder 无法使用的复杂自定义类型或模型,或 (2) 使用自定义命名约定的情况。
Actually, your ModelBinder and model will work as defined.
The component tripping you up is the view. If you use the following:
then the view will generate the correctly named elements to be consumed by your custom ModelBinder.
However, in this scenario, you do not need a custom ModelBinder, as the DefaultModelBinder will handle your nested model as long as MVC's conventions are followed. Generally, a custom ModelBinder is for (1) a complex custom type or model, which the DefaultModelBinder cannot consume, or (2) where you are using a custom naming convention.
看来这是因为您甚至没有要绑定的 Truck 对象(但这实际上可能不是问题),而且我收集您的视图也没有以正确的格式写出来。为了绑定集合,您必须符合 Phil Haacks 博客
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
您的元素符合此命名约定吗?
It seems it's because you don't even have a Truck object to bind (this may not actually be a prob though) and I'm gathering your view isn't writing it out in the proper format either. In order to bind collections you must fit a certain naming format that is covered on Phil Haacks blog
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
Are your elements fitting this naming convention?