【发布时间】:2011-04-11 18:38:57
【问题描述】:
我有一个这样的模型:
public class Person
{
public int ID { get; set; }
[Required(ErrorMessage="Name cant be empty")]
public string Name { get; set; }
public Person Friend { get; set; }
}
我想创建一个新的 Person,并使用强类型 HtmlHelper 制作了一个包含字段的表单
- 身份证
- 姓名
- 朋友 ID(下拉菜单,带有
<option value="Friend.ID">Friend.Name</option>等选项
发布表单时,我的控制器接收一个 Person 对象 (p),该对象使用默认的模型绑定器绑定。明确地说,modelbinder 执行以下操作:ID 和 Name 属性按预期绑定。 Friend 设置为一个新的Person 实例,其ID 等于我在下拉列表中选择的人的ID。 Friend.Name 的值是 null,因为我没有在表单中为其提供值。
问题:如果RequiredAttribute 文本框为空,我希望Name 文本框为空 - 确实如此。问题是它也会触发Friend 的名称属性。因此,当我发布并填写所有字段时,我发现 ModelState 无效并且错误是 p.Friend.Name 是必需的。
我将如何解决这个问题?当然,在这种情况下,我不想验证 Friend 的属性。我想过:
- 为我的视图使用 ViewModel,这会以某种方式解决我的问题。我还没有尝试过,因为我觉得我真的不需要解决这么简单的问题
- 将朋友的 ID 作为单独的参数
friend_id发送,并手动绑定Friend属性。仅绑定了发布者的ID和Name属性,我手动设置了Friend属性。这涉及使用friend_id从我的存储库中获取Friend以使其成为“真正的”Person 对象。 - 检查 ModelState 并删除我知道不算数的错误。这是完全错误且不可扩展的(如果我添加例如
SecondFriend属性,必须记住这样做
我觉得选项 2 是最可行的,但理想情况下我希望它是自动的。另外,我不能使用强类型帮助器,因为friend_id文本框的name属性必须与操作方法的参数名称匹配。
我觉得我错过了一些让这更容易的点。希望我是对的。虽然我认为使用 ViewModel 有点乏味,但这是正确的做法,请告知。
编辑
现在使用 ViewModels 解决了这个问题,ID、Name 和 Friend_id 作为其属性和与 Person 模型相同的验证属性。然后我将ID 和Name 值映射到一个新的Person 实例。然后通过从存储库加载指定的朋友来设置 Friend 属性。赞newPerson.Friend = repository.Get(viewModel.Friend_id)
当我有时间计划仔细查看AutoMapper 以“自动”执行此操作时。
【问题讨论】:
-
你不能在你的控制器方法上使用 bind
来防止模型绑定器尝试绑定/更新/验证朋友吗? -
是的,与解决方案 2 相结合是我想象的最终落脚点。我只是想知道我是否错过了一些重要的事情
标签: asp.net-mvc validation model-binding