如何在MVC5中自定义验证集合

时间:2014-11-27 11:56:22

标签: validation asp.net-mvc-5

我正在构建一个MVC5应用程序,我有以下viewmodels:

public class UserPartyViewModel
{
    public UserPartyViewModel()
    {
        Entitlements = new Collection<AssignedClaims>();
    }

    public Guid PartyID { get; set; }
    public string PartyName { get; set; }

    public ICollection<AssignedClaim> AssignedClaims{ get; set; }
}

public class AssignedClaims
{
    public AssignedClaims()
    {
        ClaimValues = new Collection<AssignedClaimValue>();
    }

    public string Name { get; set; }
    public int Max { get; set; }
    public int Min { get; set; }

    public ICollection<AssignedClaimValue> ClaimValues { get; set; }
}

public class AssignedClaimValue
{
    public Guid ClaimValueID { get; set; }
    public string ClaimValue { get; set; }
    public bool Assigned { get; set; }
}

UserPartyViewModel中包含的将始终是一个名为&#34; Security&#34;以及声明值为&#34;用户&#34;

的已分配索赔

如果用户的ClaimValue是Assigned,那么我需要验证模型的其余部分。如果不是,则不应进行进一步的验证。

在AssignedClaims中有一个最小值和最大值,这些是应该分配的最小和最大分配值。

我试图使用AttributeValidate无法阻止它验证模型的其余部分。

我还查看了IValidatableObject接口,但也无法根据用户声明解决如何控制子集合的验证。

实现这一目标的最佳途径是什么?

1 个答案:

答案 0 :(得分:0)

找到一个似乎可以做我想要的解决方案:

public class UserPartyViewModel : IValidatableObject
{
    public UserPartyViewModel()
    {
        Entitlements = new Collection<AssignedClaims>();
    }

    public string AccessLevel { get; set; }

    public Guid PartyID { get; set; }

    public string PartyName { get; set; }

    public ICollection<AssignedClaims> Entitlements { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var isUser = Entitlements.Any(c => c.Name == "Security" && c.ClaimValues.Any(v => v.Assigned == true && v.ClaimValue == "User"));

        if (isUser)
        {
            int i = 0;
            foreach (var result in Entitlements)
            {
                yield return result.Validate(i++);
            }
        }
        else
        {
            yield return ValidationResult.Success;
        }
    }
}

public class AssignedClaims
{
    public AssignedClaims()
    {
        ClaimValues = new Collection<AssignedClaimValue>();
    }

    public string Name { get; set; }
    public string Description { get; set; }
    public int Max { get; set; }
    public int Min { get; set; }

    public ICollection<AssignedClaimValue> ClaimValues { get; set; }


    public ValidationResult Validate(int item)
    {

        int min = Min;
        int max = (ClaimValues.Count() < Max) ? ClaimValues.Count() : Max;
        int assignedCount = ClaimValues.Where(i => i.Assigned == true).Count();

        if (!(min <= assignedCount && assignedCount <= max))
        {
            string errMessage = String.Format("{2} should have between {0} and {1} Security Claims checked.", min, max, Name);
            return new ValidationResult(errMessage, new[] { string.Format("Entitlements[{0}]", item) });
        }
        else
        {
            return ValidationResult.Success;
        }

    }

}

我遇到的唯一问题是尝试将错误消息显示在正确的位置。在我对分配索赔的看法中,我补充说:

@Html.ValidationMessageFor(model => model, "", new { @class = "text-danger" })

并将迭代传递给assignedclaim上的validate函数,以确保它已添加到正确的成员中。