【问题标题】:Validation on an entire Class MVC3 C#验证整个类 MVC3 C#
【发布时间】:2012-05-31 05:09:54
【问题描述】:

目前我有一个用户可以部分创建的客户类,并完成详细信息。例如它看起来像这样

新客户

    [Required(ErrorMessage = "Business name is required.")]
    [Display(Name = "Business Name:")]
    public string BusinessName { get; set; }

    [Display(Name = "Address:")]
    public string Address { get; set; }

    [Display(Name = "City:")]
    public string City { get; set; }

    [Display(Name = "State:")]
    public string State { get; set; }

    [Display(Name = "Zip:")]
    public string Zip { get; set; }

客户结帐

    [Required(ErrorMessage = "Business name is required.")]
    [Display(Name = "Business Name:")]
    public string BusinessName { get; set; }

    [Required(ErrorMessage = "Address is required.")]
    [Display(Name = "Address:")]
    public string Address { get; set; }

    [Required(ErrorMessage = "City is required.")]
    [Display(Name = "City:")]
    public string City { get; set; }

    [Required(ErrorMessage = "State is required.")]
    [Display(Name = "State:")]
    public string State { get; set; }

    [Required(ErrorMessage = "Zip is required.")]
    [Display(Name = "Zip:")]
    public string Zip { get; set; }

当用户结帐时,我需要确保他们完成填写信息(如果缺少某些信息)。 我的想法是创建一个 Customer Checkout 类,其中填充了他们创建新客户时的信息,并在将它们传递给结帐之前检查它是否有效。我的问题是我知道的唯一方法是对照 string.isNullOrEmpty() 检查每个字段,但我知道必须有更好的方法。我将不得不检查 25 个这样的字段。我知道您可以检查模型是否有效,但我需要在我的数据访问层检查中的类级别执行此操作,以确保所有 [必需] 字段都有数据。希望我只是忽略了一些东西

几乎就像我需要一些方法来做类似的事情

bool hasErrors = false 

foreach attribute in my class 
if it is marked as [required]
check to make sure not null or empty
if it is set hasErrors = true

谢谢!

【问题讨论】:

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


【解决方案1】:

如果性能不是考虑因素,您可以使用反射来自动验证您的对象。

static class ObjectValidator
{
    public static bool IsValid(object toValidate)
    {
        Type type = toValidate.GetType();
        var properties = type.GetProperties();
        foreach(var propInfo in properties)
        {
            var required = propInfo.GetCustomAttributes(typeof(RequiredAttribute), false);
            if (required.Length > 0)
            {
                var value = propInfo.GetValue(toValidate, null);
                // Here you'll need to expand the tests if you want for types like string
                if (value == default(propInfo.PropertyType))
                    return false;
            }
        }
        return true;
    }
}

【讨论】:

    【解决方案2】:

    您需要为您的模型创建自定义验证,

    实现接口IValidatableObject 并覆盖实现方法Validate 并创建您的自定义验证例如

    public class Foo : IValidatableObject
    {
    
          public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
          {
              //make your custom rules for validation on server side
            if ((fooAttribute== true) && (fooAtribute2 == String.Empty))
            {
                yield return new ValidationResult("Your custom Error");
            }
          }
    
    } 
    

    NOTE: 这样您就可以在应用程序的服务器端实现验证

    【讨论】:

    • 为什么每个建议 IValidateableObject 的人都忽略了它不做客户端验证?如果您混合使用客户端验证和仅服务器端验证,这是站点如何运行的一个重要方面。如果忽略提及这一点,您会对您试图帮助的人造成严重伤害,因为他们可能不明白为什么他们的验证工作流程是疯狂的。
    • 但在示例代码中,我以注释形式表示该代码用于服务器端验证......我的意思是,我知道可能更清楚,但我在答案中提到......
    • 我的问题是,最终它与我现在所做的并没有太大的不同。我有一个方法可以检查 25 个字段中的每一个,而不是自定义验证器。我只是好奇是否有一种方法可以验证一个类,而不是使用我已经在构造函数中定义的 [Required] 属性进行建模。
    • 我不知道,通过我回答的方法,您可以处理错误并使用 ModelState.IsValid 方法,而无需调用特定方法进行验证,并且捕获的错误将在何时自动呈现您需要在您的视图中,基于您视图的ValidationMessageFor
    猜你喜欢
    • 1970-01-01
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    • 2014-01-21
    • 2012-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多