【问题标题】:How to manually validate a model with attributes?如何手动验证具有属性的模型?
【发布时间】:2013-06-16 23:40:46
【问题描述】:

我有一个名为User 的类和一个属性Name

public class User
{
    [Required]
    public string Name { get; set; }
}

我想验证它,如果有任何错误添加到控制器的ModelState 或实例化另一个模型状态...

[HttpPost]
public ActionResult NewUser(UserViewModel userVM)
{
    User u = new User();
    u.Name = null;

    /* something */

    // assume userVM is valid
    // I want the following to be false because `user.Name` is null
    if (ModelState.IsValid)
    {
        TempData["NewUserCreated"] = "New user created sucessfully";

        return RedirectToAction("Index");
    }

    return View();
}

属性适用于UserViewModel,但我想知道如何验证类而不将其发布到操作中。

我怎样才能做到这一点?

【问题讨论】:

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


    【解决方案1】:

    您可以使用Validator 来完成此操作。

    var context = new ValidationContext(u, serviceProvider: null, items: null);
    var validationResults = new List<ValidationResult>();
    
    bool isValid = Validator.TryValidateObject(u, context, validationResults, true);
    

    【讨论】:

    • 一个疑问:为什么不直接使用System.Web.Mvc.Controller.TryValidateModel(u)方法?
    • @GianpieroCaretti 因为这提供了不需要的参考?大多数时候,这很可能在控制台应用程序或库中使用。当涉及到 Web 应用程序时,在正常情况下几乎不需要这样做。
    • @Viezevingertjes:我同意。
    【解决方案2】:

    我在 Stack Overflow 文档中做了一个解释如何做到这一点的条目:

    验证上下文

    任何验证都需要一个上下文来提供有关正在验证的内容的一些信息。这可以包括各种信息,例如要验证的对象、一些属性、要在错误消息中显示的名称等。

    ValidationContext vc = new ValidationContext(objectToValidate); // The simplest form of validation context. It contains only a reference to the object being validated.
    

    创建上下文后,有多种验证方式。

    验证对象及其所有属性

    ICollection<ValidationResult> results = new List<ValidationResult>(); // Will contain the results of the validation
    bool isValid = Validator.TryValidateObject(objectToValidate, vc, results, true); // Validates the object and its properties using the previously created context.
    // The variable isValid will be true if everything is valid
    // The results variable contains the results of the validation
    

    验证对象的属性

    ICollection<ValidationResult> results = new List<ValidationResult>(); // Will contain the results of the validation
    bool isValid = Validator.TryValidatePropery(objectToValidate.PropertyToValidate, vc, results, true); // Validates the property using the previously created context.
    // The variable isValid will be true if everything is valid
    // The results variable contains the results of the validation
    

    还有更多

    要了解有关手动验证的更多信息,请参阅:

    【讨论】:

    • 请记住在验证属性时在验证上下文中指定MemberName,例如vc.MemberName = nameof(objectToValidate.PropertyToValidate);
    【解决方案3】:

    我编写了一个包装器,以使其使用起来不那么笨重。

    用法:

    var response = SimpleValidator.Validate(model);
    
    var isValid = response.IsValid;
    var messages = response.Results; 
    
    

    或者,如果您只关心检查有效性,那就更严格了:

    var isValid = SimpleValidator.IsModelValid(model);
    
    

    完整来源:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    namespace Ether.Validation
    {
        public static class SimpleValidator
        {
            /// <summary>
            /// Validate the model and return a response, which includes any validation messages and an IsValid bit.
            /// </summary>
            public static ValidationResponse Validate(object model)
            {
                var results = new List<ValidationResult>();
                var context = new ValidationContext(model);
    
                var isValid = Validator.TryValidateObject(model, context, results, true);
             
                return new ValidationResponse()
                {
                    IsValid = isValid,
                    Results = results
                };
            }
    
            /// <summary>
            /// Validate the model and return a bit indicating whether the model is valid or not.
            /// </summary>
            public static bool IsModelValid(object model)
            {
                var response = Validate(model);
    
                return response.IsValid;
            }
        }
    
        public class ValidationResponse
        {
            public List<ValidationResult> Results { get; set; }
            public bool IsValid { get; set; }
    
            public ValidationResponse()
            {
                Results = new List<ValidationResult>();
                IsValid = false;
            }
        }
    }
    

    或者在这个要点:https://gist.github.com/kinetiq/faed1e3b2da4cca922896d1f7cdcc79b

    【讨论】:

      【解决方案4】:

      由于问题是专门询问 ASP.NET MVC,您可以在 Controller 操作中使用 TryValidateObject

      你想要的方法重载是TryValidateModel(Object)

      验证指定的模型实例。

      如果模型验证成功,则返回 true;否则为假。

      你修改的源代码

      [HttpPost]
      public ActionResult NewUser(UserViewModel userVM)
      {
          User u = new User();
          u.Name = null;
      
          if (this.TryValidateObject(u))
          {
              TempData["NewUserCreated"] = "New user created sucessfully";
              return RedirectToAction("Index");
          }
      
          return View();
      }
      

      【讨论】:

      • 很好,但是如果TryValidateObject 失败是什么原因呢?我想了解有关验证的更多详细信息?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-24
      相关资源
      最近更新 更多