标准验证覆盖MVC自定义验证

时间:2016-03-16 11:29:38

标签: c# asp.net-mvc validation asp.net-mvc-4

我的自定义验证有问题。我有一个ViewModel:

public class CityViewModel
{
    [ForeignKey(ErrorMessageResourceName = "County")]
    public int CountyId { get; set; }

    public string PostCode { get; set; }
}

我创建了一个名为ForeignKey的自定义验证类,其中包含以下代码:

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)]
public class ForeignKeyAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        PropertyInfo propretyInfo = validationContext.ObjectType.GetProperty(validationContext.MemberName);
        ResourceManager manager = Resource.ResourceManager;

        if (propretyInfo.PropertyType.IsGenericType && propretyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) {
            if (value != null && (int)value == 0) {
                return new ValidationResult(manager.GetString(ErrorMessageResourceName));
            }
            else {
                return ValidationResult.Success;
            }
        }
        else if (value == null || (int)value == 0) {
            return new ValidationResult(manager.GetString(ErrorMessageResourceName));
        }

        return ValidationResult.Success;
    }
}

此方法可以正常工作并正确返回错误。问题在于我的控制器中的操作:

[HttpPost]
public ActionResult Create(DataSourceRequest request, CityViewModel model)
{
    try {
        if (ModelState.IsValid) {
            // Some code

            return Json(new[] { model }.ToDataSourceResult(request, ModelState));
        }
    }
    catch (Exception e) {
        // Some code
    }

    return Json(ModelState.ToDataSourceResult());
}

如果CountyId为空(确实为0但在验证之前输入方法Create可能为空)我的ModelState包含CountyId字段,此错误“必须使用CountyId字段。”而不是我的错误传递给ForeignKey自定义属性。

如果我使用此代码:

TryValidateModel(model);

然后ModelState包含两个错误,因此在调用TryValidateModel之前我应该​​使用:

ModelState["CountyId"].Errors.Clear();

如何判断MVC在第一次验证时不会覆盖我的错误?我更喜欢简单地使用ModelState.IsValid。有人可以帮帮我吗?

1 个答案:

答案 0 :(得分:1)

尝试在“创建方法参数”中排除ID

[HttpPost] 
public ActionResultCreate([Bind(Exclude = "Id")], CityViewModel model)