【问题标题】:C# MVC5 Validate in Model with a ListC# MVC5 使用列表在模型中验证
【发布时间】:2015-09-20 23:41:04
【问题描述】:

在一个类中,我有一个允许的静态值列表

private static List<string> allowedClassNames = new List<string> {"Real Estate", "Factored Debt"}; 

我也有该类的一个属性,我想将其限制为该列表中的值。

        [Required]
        public string assetClassName { get; set; }

我想在模型级别执行此操作,因此它可以在 REST 或视图上下文中工作。

我将如何强制将提交中的值限制在该列表中?

谢谢!

这是我结束的地方 - 尚未完全测试,但为未来的海报提供一个想法。

    class MustContainAttribute : RequiredAttribute
{
    public string Field { get; private set; }
    List<string> allowed;

    public MustContainAttribute(string validateField)
    {
        this.Field = validateField;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        switch (Field)
        {
            case "assetClassName":
                allowed = new List<string> { "Real Estate", "Factored Debt" }; 
                break;
            default:
                return ValidationResult.Success;
        }

        if (!allowed.Contains(Field))
        {
            return new ValidationResult("Invalid Value");
        }else{
            return ValidationResult.Success;
        }

    }

}

【问题讨论】:

  • 使用RegularExpressionAttribute 来限制值,或者编写自己的验证属性(比如)[MustContain("allowedClassNames")] 并在IsValid() 方法中,将值与其他属性中的值进行比较跨度>
  • 另一种方法是对属性使用枚举。如果恶意用户尝试提交除枚举值之一以外的任何内容,ModelSate 将无效

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


【解决方案1】:

创建自定义验证属性:

public class ClassNameRequiredAttribute : RequiredAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext context)
    {

        Object instance = context.ObjectInstance;
        Type type = instance.GetType();
        MyAssetClass myAssetClass = (MyAssetClass)type.GetProperty("MyAssetClass").GetValue(instance, null);

        if (!string.IsNullOrEmpty(myAssetClass.assetClassName))
        {
            if (myAssetClass.allowedClassNames.Contains(myAssetClass.assetClassName))
            {
                return ValidationResult.Success;
            }
        }
        return new ValidationResult(ErrorMessage);
    }
}

在你的模型中:

    [ClassNameRequired(ErrorMessage="Your error message.")]
    public string assetClassName { get; set; }

【讨论】:

  • 以这种方式使用ValidationAttribute 没什么意义 - 与模型中的特定属性相关联。您也可以在控制器方法中使用 2 行代码来完成此操作
  • 我同意,但他/她问如何在模型级别做到这一点。正则表达式是个好主意,但你知道那句话……知道他们有两个问题。
  • 如果您要这样做,那么该属性需要具有其他值的属性(List),以便灵活且可以重复使用
  • 我使用了这个的修改版本,引入我要验证的字段名称,然后在 ValidationResult 方法中进行切换,以根据我正在验证的字段名称加载适当的值.所以它是可重复使用的。谢谢你们的帮助!
  • @DiscontentDisciple 没问题!很高兴听到您提出解决方案。
【解决方案2】:

如 cmets 中所述,您可以创建自己的 ValidationAttribute。如果您在多个模型上进行此验证,或者您还想实现客户端验证 (JavaScript),这将非常有用

但是,像这样进行一次性验证的一种快速简便的方法是 IValidatableObject。您可以按如下方式使用它:

public class AssetModel:IValidatableObject
{
    private static List<string> allowedClassNames = new List<string> {"Real Estate", "Factored Debt"};

    [Required]
    public string assetClassName { get; set; }
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (!allowedClassNames.Contains(assetClassName)
        {
            yield new ValidationResult("Not an allowed value", new string[] { "assetClassName" } );
        }
    }
}

【讨论】:

    猜你喜欢
    • 2021-09-07
    • 1970-01-01
    • 2020-11-30
    • 1970-01-01
    • 2021-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多