【发布时间】:2015-07-24 17:39:39
【问题描述】:
给出了以下约定。每个Action 都有一个BaseRequest 类型的参数,其数据取决于Action。 ViewModel 始终是 BaseResponse 类型。
我想做的是,如果View 包含一个表单,那么POST-Action 需要某种BaseRequest。
在ViewModel 是BaseResponse 时,如何实现正确的模型绑定?
我已经尝试在XYZResponse 中添加XYZRequest 的属性,所以我可以像这样绑定
@Html.ChecBoxFor(m => m.RequestObject.SomeBooleanProperty)
但这会生成name RequestObject.SomeBooleanProperty,它不会正确绑定到接受XYZRequest的POST-Action。
这种约定是完全错误的还是我遗漏了什么?
更新 #1
我还尝试创建一个 XYZRequest 类型的新 temporary 对象并像这样绑定到它
@Html.CheckBoxFor(m = tmpReq.SomeBooleanProperty)
这将呈现 tmp.SomeBooleanProperty 的 name 也无法绑定。
更新 #2 - 附加信息
设置了以下结构。
-
BaseRequest是abstract -
GetOverviewRequest:BaseRequest -
GetOverviewRequest具有string、int或任何其他复杂类型甚至Lists或Dictionaries类型的属性
如果继承自BaseResponse 的GetOverviewResponse 被返回给View 并提供一个名为TheProperty 的属性,类型为GetOverviewRequest 绑定失败 p>
@Html.TextBoxFor(m => m.TheProperty.SomeBooleanValue)
将尝试绑定到 GetOverviewRequest 对象中的 TheProperty-property,该对象不存在。
如果GetOverviewRequest 有一个名为TheProperty 的属性要绑定,这可能会起作用。但是如果命名不同,绑定也会失败。
我只想要类似的东西
<input name="SomeBooleanValue">
<input name="SomeComplexType.SomeStringValue">
而不是
<input name="TheProperty.SomeBooleanValue">
<input name="TheProperty.SomeComplexType.SomeStringValue">
更新 #3 - 添加示例项目
Sample project via dropbox.com
更新 #4 - 解释,为什么 @StephenMuecke 的解决方案不起作用
如cmets中所说,其他问题的解决方案需要知道GetOverviewResponse-object中的属性名称。该属性名为TheProperty,因此我必须添加[Bind(Prefix = "TheProperty)] 才能启用正确绑定。我真的不喜欢魔线。而"TheProperty" 是一个神奇的字符串。如果把TheProperty的名字改成RenamedProperty,整个绑定就会失败。
所以。我现在正在寻找一种动态设置前缀的方法。
[Bind(Prefix = GetOverviewResponse.NameOf(m => m.TheProperty))]
真的很棒。也许某种自定义属性?由于 BindAttribute 是密封的,因此没有机会创建一个继承自此的属性。
有什么想法吗?
【问题讨论】:
-
你能把你正在使用的模型贴在页面上吗?
-
@Robert 添加了该项目。这有帮助吗?
-
@StephenMuecke 这可以解决问题。但我正在寻找更有活力的东西。因为如果更改名称
TheProperty但没有更改绑定前缀,这也会失败。任何想法如何动态地做到这一点?像[Bind(Prefix=new ResponseObject().GetPropertyName(TheProperty))]或类似的东西? -
不,这里没有内置的东西可以做到这一点 - 你必须编写自己的自定义
ModelBinder。
标签: c# asp.net-mvc-4 razor extension-methods model-binding