MVC3删除ModelState错误


83

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

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

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

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

我的问题是...如何关闭ServerSide验证?我不希望用户单击此按钮时显示“验证摘要”信息。我知道您可以使用此添加自定义模型错误

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 => ModelState.Keys.Contains(key))?似乎Where子句是多余的,因为ModelState.Keys中的每个键都会使其ModelState.Keys.Contains(key)返回true。
Maxim Zaslavsky

1
我已经更新了问题和文本,以在ModelState.ContainsKey上使用较短的方法,尽管您的假设是错误的。这些都在做同样的事情。
杰夫·雷迪

抱歉,我可能解释得不好或误解了您的答复。您是对的,ModelState.ContainsKey(key)并且ModelState.Contains(key)做相同的事情,但是我的意思是,ModelState.Keys.ToList()will中的所有值本质上都包含在中ModelState,因此整个Where子句是多余的,并且会降低性能。小事,虽然。
Maxim Zaslavsky

那是ReSharper一起提出来的。感谢您指出了这一点。
杰夫·雷迪

1
只要注意您发现哪个按钮是提交源的方式即可。在ViewModel中,您不必具有此属性。只需将FormCollection参数添加到Controller:public ActionResult Index(YourViewModelClass模型,FormCollection formCollection)。并检查按钮名称是否在其中:if(formCollection [“ UploadImageButton”]!= null)。我认为最好有更多的提交按钮。
jannagy02 2013年

Answers:


144

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

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

1
这正是我想要的。我已经更改了我选择的答案(对不起,亚当·普莱默斯)。
杰夫·雷迪

谢谢,这节省了我几个小时!
Agent007

1
以防万一有人想知道,这也会影响ModelState.IsValid
Red Taz

2
奇怪的是,这对我来说还不够。我必须添加ModelState [“ {key}”]。ValidationState = ModelValidationState.Valid;
AGuyCalledGerald '17年

67

这建立在以前的答案的基础上,但又简化了一点:

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

7

通常,您不想关闭服务器端验证或手动删除ModelState错误。这是可行的,但容易出错,因为它必须依赖字符串作为键。由于它是正确且有用的,因此我对如何删除键的答案表示赞同,但我建议您不要将自己设计为必须认真考虑的情况。

对于您的情况,您对于同一个表单有多个提交按钮,但是在上载图像时实际上并没有提交表单。为了防止客户端验证,您可以按照已经说明的方式使用“取消”类,但是我也建议您使用另一种形式的第二个提交按钮,在这种情况下,它不会对您的主窗体进行验证。

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

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

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

这样可以避免依赖于正确的键名,但是可以保留模型中已经存在的任何值(有效值或无效值)。

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


7

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

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

它可以流畅地用于清除多个字段的错误。


3

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

ModelState.Remove("{key}");
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.