如何使用DataAnnotations进行服务器端验证

时间:2013-12-03 17:57:07

标签: asp.net-mvc validation asp.net-mvc-5

我正在使用ASP.NET MVC 5并尝试使用在控制器post方法中实例化并从EF重新加载的视图模型对象的数据注释来进行自定义验证。从客户端发布时只填充少数模型属性,其余的使用EF重新加载。该模型很复杂,它的所有部分都实现了IValidatableObject。在正确加载所有内容后,Validate方法中的代码将触发新视图模型,但它不会对应用于模型的数据注释执行任何操作。

因此,例如,如果我的模型具有应用于字段的EmailAddress属性,则它在客户端上运行良好,但在针对新视图模型进行验证时会在服务器端忽略它。如何使用Validate方法将数据注释考虑在内?

以下是控制器操作的代码......

[HttpPost]
[ValidateAntiForgeryToken]
public virtual ActionResult SignUp(SignUpEM em) {
    if (em == null) {
        return RedirectToAction(MVC.Sheet.Index());
    }
    SignUpSheet signUpSheet = db.GetSignUpSheet(em.SheetId);
    SignUpEM newEM = Map.ToSignUpEM(signUpSheet);
    foreach (var sourceField in em.Fields) {
        FieldEM targetField = newEM.Fields.FirstOrDefault(f => f.FieldDefId == sourceField.FieldDefId && f.Id == sourceField.Id);
        if (targetField.FieldType.IsEditable()) {
            if (targetField.FieldType.IsBoolean()) {
                ((BooleanFieldEM)targetField).BooleanValue = ((BooleanFieldEM)sourceField).BooleanValue;
            }
            else {
                targetField.Value = sourceField.Value;
            }
            targetField.SetFullyLoaded();
        }
    }
    // This line is here to simulate an invalid value passed into an email field.
    newEM.Fields[0].Value = "invalid";
    newEM.SetFullyLoaded();
    ModelState.Clear();
    var validationResults = new List<ValidationResult>();
    Validator.TryValidateObject(newEM, new ValidationContext(newEM, null, null), validationResults, true);
    foreach (var result in validationResults) {
        if (result == null) { continue;  } // otherwise we need to avoid duplicates.
        if (result.MemberNames.Count() == 0)
            ModelState.AddModelError(String.Empty, result.ErrorMessage);
        else
            foreach (var name in result.MemberNames)
                ModelState.AddModelError(name, result.ErrorMessage);
    }

    if (!ModelState.IsValid) {
        return View(newEM);
    }

    SignUp su = Map.ToSignUp(em);
    db.AddSignUp(su);
    return RedirectToAction(MVC.SignUp.SignUp(em.SheetId));
}

这是SignUpEM的验证码......

private bool fullyLoaded;
internal void SetFullyLoaded() {
    fullyLoaded = true;
}

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
    if (fullyLoaded) {
        foreach (var f in Fields)
            foreach (var vr in f.Validate(validationContext))
                yield return vr;

        if (ListIntro == null)
            yield return new ValidationResult("ListIntro is required for now.");
    }
}

FieldEM的验证码......

private bool fullyLoaded;
internal void SetFullyLoaded() {
    fullyLoaded = true;
}

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
    if (fullyLoaded) {
       if (Optional == false && String.IsNullOrEmpty(Value)) {
            string message = string.Format("{0} is required.", DisplayName);
            yield return new ValidationResult(message);
        }
    }
}

0 个答案:

没有答案