MVC3删除模型状态错误

我有一个情况,我正在上传一个图像用户已经从他的本地文件系统选择。在我的视图中,我的 Form 基本上有两个提交按钮。一个用于正常提交表单,并执行所有验证。第二个只是上传图片,在这种情况下,我还不想验证。

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

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

现在,当我回发时,我的模型有一个属性 UploadImageButton,当单击这个按钮时,它将填充这个属性(输入的名称与 Property 匹配)。这样,我就可以知道表单是通过真正的 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
}
82132 次浏览

You can remove model errors by doing something like this:

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

This builds off previous answers, but simplifies it a little more:

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

In general, you don't want to turn off the server-side validation or remove ModelState errors manually. It's doable, but error-prone since it must rely on strings as keys. I upvoted the answer on how to remove the keys, because it is correct and useful, but I recommend against designing yourself into a case where you must strongly consider it.

In your case, you have multiple submit buttons for the same form, but you really aren't submitting the form when you upload the image. To prevent the client-side validation, you can use the "cancel" class as you've already indicated, but I also recommend having the 2nd submit button in a different form, in which case it causes no validation on your main form.

There is a second advantage to using the different form: you can send it to a different ActionResult method which would just handle the logic of uploading the image. This different method would simply not bother to check the "IsValid" property of the model state: it only cares if there is information in the image, and that can be checked separately. (Even if you use the same ActionResult method, you can funnel the logic so that you don't rely on the IsValid property of the model state.)

If you must clear the errors from the model state, and it makes sense to clear all of them, try this:

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

This keeps you from depending on getting the key names correct, but preserves the values should any values (valid or invalid) already exist in the model.

One last thing to check for in these cases is whether you have values that are only sometimes in the view, which will not cause client-side validation (they're not in the view), but do result in server-side validation issues. In this case, it's best to use @Html.HiddenFor(model => model.PropertyName, if you can, assuming the value has already been set, it just isn't visible in this view.

I use it sometimes, so I've made an extension method out of it:

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

It can be used fluently to clear error for multiple fields.

use ModelState.Remove("{key}") to remove the error from model , which will reset the ModelState.IsValid to true

ModelState.Remove("{key}");
ModelState.ClearValidationState("KeyName");
ModelState.MarkFieldValid("KeyName");

Here's code that loops through all the errors and removes the ones that are NOT in the desired page. I have two pages and I only want to show the errors for the 1st page. (The 2nd page is hidden but will be visible later when page 1 is hidden.) You simply get the errors and loop through and remove the errors that are not in the currently visible page. PageNum is an integer set earlier.

var errors = ModelState.Keys.Where(k => ModelState[k].Errors.Count > 0).Select(k => new { propertyName = k, errorMessage = ModelState[k].Errors[0].ErrorMessage });


bool isError = false;


foreach (var error in errors)
{
isError = CheckForErrors(error.propertyName, pageNum);
ModelState.Remove(error.propertyName);
}


private bool CheckForErrors(string propertyName, int page)
{
var Page1Properties = new Dictionary<string, string>();
Page1Properties.Add("biz_dbaBusinessName", "biz_dbaBusinessName");


var Page2Properties = new Dictionary<string, string>();
Page2Properties.Add("bank_name", "bank_name");


string result;


switch (page)
{
case 1:
return (Page1Properties.TryGetValue(propertyName, out result));
break;
case 2:
return (Page2Properties.TryGetValue(propertyName, out result));
break;
default:
break;
}


return false;
}