帮助在 .net 中进行 ModelBinding 复杂对象
我有一个自定义模型绑定器来处理我的 accountRequest 类。 此类由一些布尔值和 UserViewModel 组成。
UserViewModel 由名字、姓氏、地址等字符串组成。
最初我只是将 UserViewModel 作为操作参数传递,但现在我需要将 UserViewModel 打包到 accountRequest 中。
但是,现在我的 modelbinder 不会将 httpContext.Request 中的字符串映射到 AccountRequest 内的 UserViewModel 。所有布尔值映射都很好。
除了硬编码之外,是否有一种简单的方法可以将他的数据映射到 UserViewModel 属性?
我尝试过这个,但我不喜欢它。 (简化)
Dim accountRequest As New AccountRequest
Dim user As New UserViewModel
If Not String.IsNullOrEmpty(controllerContext.HttpContext.Request("Firstname")) Then
user.FirstName = controllerContext.HttpContext.Request("Firstname")
End If
accountRequest.CurrentUser = user
Return accountRequest
显然,我们非常感谢任何帮助。提前致谢!
I have a custom modelbinder built to handle my accountRequest class.
This class consists of some boolean values and a UserViewModel.
The UserViewModel is made up of strings such as Firstname, Last Name, Address.
Originally I was just passing the UserViewModel as the action parameter but I now I need to package UserViewModel inside of accountRequest.
however, now my modelbinder will not map the strings in the httpContext.Request to my UserViewModel inside of AccountRequest. All of the booleans map just fine.
Is there an easy way to get his data to map to the UserViewModel properties other than hardcoding it?
I have attempted this but I dont like it. (simplified)
Dim accountRequest As New AccountRequest
Dim user As New UserViewModel
If Not String.IsNullOrEmpty(controllerContext.HttpContext.Request("Firstname")) Then
user.FirstName = controllerContext.HttpContext.Request("Firstname")
End If
accountRequest.CurrentUser = user
Return accountRequest
Obviously any help is greatly appreciated. Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
抱歉 - 刚刚意识到您的代码是 VB,而我已经用 C# 进行了回答
这可能是因为模型绑定器现在正在查找
modelname.property
而不仅仅是 ValueProvider 中的property
,而且以前,因为它是直接操作方法参数,所以它只会查找property
。现在模型类型是另一个模型类型的成员,它的属性名称将用作前缀,我不相信您可以删除该要求(可以尝试
Bind(Prefix="" )
参数,但我认为这不会起作用)。这是假设您没有自定义绑定每个属性,并且
DefaultModelBinder
正在为您执行其中一些属性。您应该能够通过将查询字符串更改为
?modelname.property=[value]
来使其工作,而无需更改代码。如果您使用的是 Form,那么您应该考虑使用Html.EditorFor
扩展方法 - 因为它负责模型命名(只要您的 ViewModel 成员名称和输入模型名称一致)。但作为查询字符串的示例:obj.Nested.StringProperty 值可以填充:
/Index?Nested.StringValue=hello%20world
因为obj
前缀是无论如何都是隐含的。如果您不喜欢这样,您有几个选择:
1)更改方法的签名以采用两个参数:
然后在正文中立即将
nested
复制到obj .Nested
属性。这有点hacky - 但它会起作用。2) 手动强制绑定类的属性以使用
ValueProviders
中的非前缀值(但随后您将模型类型限制为仅适用于某些类型的请求 - 这不是完全灵活)。3) 或者,就像我之前所说的,如果这些属性是从 Http 表单绑定的,请使用 Html.EditorFor 生成标记 - 它会自动生成具有正确名称的输入,只要它们不存在从输入->输出不会改变。
Sorry - just realised that your code was VB and I've answered in C#
This could be because the model binder is now looking
modelname.property
instead of justproperty
in the ValueProviders and, previously, because it was a direct action method parameter, it would have just been looking forproperty
.Now that the model type is a member of another, its property name will be used as a prefix and I don't believe you can remove that requirement (could try
Bind(Prefix="")
on the parameter, but I don't think that'll work).This is assuming you aren't custom-binding every property and that the
DefaultModelBinder
is doing some of these properties for you.You should be able to make it work, without changing code, by altering your query string to be
?modelname.property=[value]
. If you're using a Form, then you should consider using theHtml.EditorFor
extension method - as it takes care of model naming (so long as your ViewModel member names and input model names are consistent). But as an example from the query string:The obj.Nested.StringProperty value can be filled with:
/Index?Nested.StringValue=hello%20world
because theobj
prefix is implicit anyway.If you don't like this, you have a couple of options:
1) Change the signature of the method to take two parameters:
And then in the body you immediately copy
nested
to theobj.Nested
property. This is a little bit hacky - but it'll work.2) Manually force the bind of your class' properties to use non-prefixed values from the
ValueProviders
(but then you're limiting your model type to only work with certain types of request - which isn't exactly flexible).3) Or, like I said earlier, if these properties are being bound from an Http Form, use
Html.EditorFor
to generate the markup - it automatically generates inputs with the correct names, so long as they don't change from input->output.