帮助在 .net 中进行 ModelBinding 复杂对象

发布于 2024-10-16 05:53:58 字数 726 浏览 2 评论 0原文

我有一个自定义模型绑定器来处理我的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

盛夏尉蓝 2024-10-23 05:53:58

抱歉 - 刚刚意识到您的代码是 VB,而我已经用 C# 进行了回答

这可能是因为模型绑定器现在正在查找 modelname.property而不仅仅是 ValueProvider 中的 property,而且以前,因为它是直接操作方法参数,所以它只会查找 property

现在模型类型是另一个模型类型的成员,它的属性名称将用作前缀,我不相信您可以删除该要求(可以尝试 Bind(Prefix="" ) 参数,但我认为这不会起作用)。

这是假设您没有自定义绑定每个属性,并且 DefaultModelBinder 正在为您执行其中一些属性。

您应该能够通过将查询字符串更改为 ?modelname.property=[value] 来使其工作,而无需更改代码。如果您使用的是 Form,那么您应该考虑使用 Html.EditorFor 扩展方法 - 因为它负责模型命名(只要您的 ViewModel 成员名称和输入模型名称一致)。但作为查询字符串的示例:

public class MyObject{
  public string StringValue { get; set; }
}

public class MyObjectOuter{
  public MyObject Nested { get; set; }
}

public ActionResult Index(MyObjectOuter obj);

obj.Nested.StringProperty 值可以填充: /Index?Nested.StringValue=hello%20world 因为 obj 前缀是无论如何都是隐含的。

如果您不喜欢这样,您有几个选择:

1)更改方法的签名以采用两个参数:

public ActionResult Index(MyObjectOuter outer, MyObject nested)

然后在正文中立即将 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 just property in the ValueProviders and, previously, because it was a direct action method parameter, it would have just been looking for property.

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 the Html.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:

public class MyObject{
  public string StringValue { get; set; }
}

public class MyObjectOuter{
  public MyObject Nested { get; set; }
}

public ActionResult Index(MyObjectOuter obj);

The obj.Nested.StringProperty value can be filled with: /Index?Nested.StringValue=hello%20world because the obj 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:

public ActionResult Index(MyObjectOuter outer, MyObject nested)

And then in the body you immediately copy nested to the obj.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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文