【问题标题】:MVC3 Remove ModelState ErrorsMVC3 删除 ModelState 错误
【发布时间】:2011-11-17 10:47:03
【问题描述】:

我遇到了一种情况,我正在上传用户从其本地文件系统中选择的图像。在我看来,我的表单基本上有两个提交按钮。一个用于正常提交表单,并执行所有验证。第二个仅用于上传图像,在这种情况下我还不想验证。

我设法通过给我的“上传图片”提交按钮一个“样式名称取消”的类值来关闭客户端验证,所以

<input type="submit" name="UploadImageButton" value="Upload Image" class="style-name cancel" /> 

现在,当我回帖时,我的模型有一个属性 UploadImageButton,当单击此按钮时,它会填充此属性(输入的名称与属性匹配)。这样,我就知道表单是由我真正的提交按钮还是由 UploadImageButton 提交的。

我的问题是…… 如何关闭服务器端验证?我不希望在用户单击此按钮时显示验证摘要信息。我知道你可以使用这个添加自定义模型错误

ModelState.AddModelError("{key}", "{error msg}");

我正在寻找消除模型错误的方法。这可能吗?

编辑:

这是我想出的:

foreach (var key in ModelState.Keys.ToList().Where(key => ModelState.ContainsKey(key))) {
     //ModelState.Remove(key); //This was my solution before
     ModelState[key].Errors.Clear(); //This is my new solution. Thanks bbak
}

【问题讨论】:

  • 你为什么要做Where(key =&gt; ModelState.Keys.Contains(key))?似乎 Where 子句是多余的,因为 ModelState.Keys 中的每个键都会有其 ModelState.Keys.Contains(key) 返回 true。
  • 我已经更新了问题和文本,以便在 ModelState.ContainsKey 上使用更短的方法,尽管您的假设是错误的。它们在做同样的事情。
  • 对不起,我可能解释得不好或误解了您的回复。 ModelState.ContainsKey(key)ModelState.Contains(key) 做同样的事情是对的,但我的观点是 ModelState.Keys.ToList() 中的所有值本质上都会包含在 ModelState 中,因此整个 Where 子句是多余的,并且将减慢性能。不过是小事。
  • 那是 ReSharper 把它放在一起的。感谢您指出这一点。
  • 请注意您找出哪个按钮是提交源的方式。在 ViewModel 中,您不必拥有此属性。只需在Controller中添加一个FormCollection参数:public ActionResult Index(YourViewModelClass model, FormCollection formCollection)。并检查按钮名称是否在其中:if (formCollection["UploadImageButton"] != null)。我认为最好有更多提交按钮。

标签: asp.net-mvc-3 validation modelstate


【解决方案1】:

您可以通过执行以下操作来消除模型错误:

if (ModelState.ContainsKey("{key}"))
    ModelState["{key}"].Errors.Clear();

【讨论】:

  • 这正是我想要的。我已经更改了我选择的答案(抱歉 Adam Tuliper)。
  • 谢谢,这节省了我几个小时!
  • 万一有人想知道,这也会影响ModelState.IsValid
  • 奇怪的是,这对我来说还不够。我必须添加 ModelState["{key}"].ValidationState = ModelValidationState.Valid;
  • 我假设您已经知道该模型中有哪些字段。 containskey 检查可能不是必需的。
【解决方案2】:

这建立在以前的答案之上,但更简化了一点:

foreach (var modelValue in ModelState.Values)
{
    modelValue.Errors.Clear();
}

【讨论】:

    【解决方案3】:

    一般来说,您不希望手动关闭服务器端验证或移除 ModelState 错误。这是可行的,但容易出错,因为它必须依赖字符串作为键。我赞成如何删除密钥的答案,因为它是正确且有用的,但我建议不要将自己设计成必须强烈考虑的情况。

    在您的情况下,您对同一个表单有多个提交按钮,但您在上传图片时实际上并没有提交表单。为了防止客户端验证,您可以使用您已经指出的“取消”类,但我也建议使用不同的表单中的第二个提交按钮,在这种情况下,它会导致您的主表单上没有验证。

    使用不同的表单还有第二个好处:您可以将它发送到一个不同的 ActionResult 方法,该方法只处理上传图像的逻辑。这种不同的方法根本不会检查模型状态的“IsValid”属性:它只关心图像中是否有信息,并且可以单独检查。 (即使您使用相同的 ActionResult 方法,您也可以汇集逻辑,这样您就不会依赖模型状态的 IsValid 属性。)

    如果您必须从模型状态中清除错误,并且清除所有错误是有意义的,请尝试以下操作:

    foreach (var key in ModelState.Keys)
    {
        ModelState[key].Errors.Clear();
    }
    

    这使您不必依赖正确的键名,但如果模型中已经存在任何值(有效或无效),则会保留这些值。

    在这些情况下要检查的最后一件事是,您的值是否有时会出现在视图中,这不会导致客户端验证(它们不在视图中),但会导致服务器端验证问题。在这种情况下,最好使用@Html.HiddenFor(model => model.PropertyName,如果可以的话,假设该值已设置,它只是在此视图中不可见。

    【讨论】:

      【解决方案4】:

      我有时会用到它,所以我用它做了一个扩展方法:

      public static ModelStateDictionary ClearError(this ModelStateDictionary m, string fieldName)
      {
          if (m.ContainsKey(fieldName))
              m[fieldName].Errors.Clear();
          return m;
      }
      

      可以流利地使用它来清除多个字段的错误。

      【讨论】:

        【解决方案5】:

        使用 ModelState.Remove("{key}") 从模型中删除错误,这会将 ModelState.IsValid 重置为 true

        ModelState.Remove("{key}");
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-07-12
          • 1970-01-01
          • 2010-12-09
          • 2012-05-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-09
          相关资源
          最近更新 更多