【问题标题】:mvc model with foreign key relationship具有外键关系的 mvc 模型
【发布时间】:2023-03-27 07:45:02
【问题描述】:

我遇到了包含异物模型的模型的数据注释验证问题。

让我们说

Class Foo
{
    public virtual Int Id {get; set;}

    [Required]       
    public virtual String Name {get; set;}
 }

 Class Bar
 {
    public virtual Int Id {get; set;}

    [Required]
    public virtual String AnotherName {get; set;}

    public virtual Foo foo  {get; set;}
 }

创建 BAR 时,FOO 不是强制性/必需的。

但是当我尝试检查 BAR 的 HTTPPOST 中的 ModelState 时,它​​说模型状态无效,并报告 FOO 列丢失。

[HTTPPOST]
public ActionResult SaveBar(BAR bar)
{
if (ModelState.IsValid)
    SaveBar(bar);

} 

我已将 FOO 设置为 null,尝试过 TryUpdateModel,但仍然没有帮助。

编辑 我正在处理实体而不是查看模型

还有……如何告诉模型绑定器在绑定 BAR 时不要检查 FOO……

编辑 修改示例..

【问题讨论】:

    标签: asp.net-mvc model-view-controller asp.net-mvc-4 data-annotations


    【解决方案1】:

    当您点击“SaveBar()”时,模型绑定器似乎将 Foo 实例化为 Bar 对象的成员。因此,正如您所期望的那样,Foo 上的属性验证会触发。

    这就是我要做的:删除属性验证,然后走一条不同的路线,可能就像您从控制器操作调用的自定义验证方法一样,用于正常的“Foo”操作。 “SaveBar()”可以检查 Foo 的默认状态并决定是否调用该验证,具体取决于。

    【讨论】:

      【解决方案2】:

      它不像你想象的那样工作。 ModelState 无效,因为您按要求声明了Foo 的字段。如果您的视图不接受和传递Foo.IdFoo.Name 的值,那么您将得到一个无效的ModelState

      【讨论】:

      • 但是在BAR中我没有按要求注释FOO,那么FOO不应该被检查....以及如何解决这个问题??
      • 是的,这是正确的,但接受输入的不是 Foo 对象本身,而是它的字段,对。所以验证是针对 Foo 的字段完成的。
      【解决方案3】:

      请勿在模型 ID 上使用 [Required]。我不确定您在这里处理的是实体还是视图模型,但总的来说,应该允许取消设置 id。对于实体,在将其保存到数据库(通常)之前不会设置 ID .

      [Required] 只有两个实际用途,因此您应该准确了解它们是什么,然后仅相应地应用属性:

      1) 在实体上,[Required] 将暗示 NOT NULL。它真的只对字符串有意义,因为默认情况下,所有其他标量类型都不是 NULL。

      2) 在用于接受来自 POST 的表单数据的视图模型上。这将要求该字段不能为空。如果您的 id 不是呈现给用户输入的表单字段(我非常怀疑它是),那么它应该 是必需的。

      【讨论】:

      • 我刚刚创建了示例(已修复,ID 未标记为必需)...但我面临的真正问题是,如何避免在 BAR 验证期间检查 FOO 的属性跨度>
      • 这是默认处理的。如果您没有在Bar 中初始化Foo,那么您的属性foo 将为空,并且由于它不是必需的,因此验证将很高兴地继续进行。但是,如果fooFoo 的一个实例,那么它必须 也有效,Bar 才有效。这只是常识;否则,ModelState.IsValid 将毫无意义,因为将实体保存到数据库之类的操作在保存 Foo 时仍然会失败。
      • 对不起,我重新更新了我的示例以更清楚...字段被定义为属性...并且它正在检查 BAR 中的 FOO...属性 n 虚拟要求来自 NHibernate
      • 你到底为什么要把标量属性虚拟化?不过,这有点离题。您添加的任何内容都不会减损我在上一条评论中所说的话。如果foo 已初始化并且具有任何 必需的属性,则它们必须 填写以供模型验证。同样,这是常识。如果Bar 具有Foo 并且Foo 无效,则Bar 本身也无效。这就像试图把引擎从你的车里拿出来,然后说汽车还有一个油门踏板,所以它应该还能继续行驶。
      • 但是 FOO 是可选的.. 我仍然必须为其提供值.. 感到困惑.. 虚拟标量属性也是 Nhibernate 的要求...
      【解决方案4】:

      @hgrathi,你不明白的是,一旦你在 Foo 中设置了 Name ,现在 Bar 下 Foo 是必需的。

      解决此问题的一种方法是通过实现 IModelBinder 创建自定义模型绑定器。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-15
        • 2011-11-15
        • 2015-12-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多