Home > Net >  How to apply C# Attributes to the type inside of a List for ASP.NET MVC Web Application
How to apply C# Attributes to the type inside of a List for ASP.NET MVC Web Application

Time:09-10

I have a model which looks like this:

public class ChartModel
{

    public List<int> GoalList { get; set; } = new List<int>();

    public List<string?> LabelList { get; set; } = new List<string?>();

    [Required]
    [StringLength(maximumLength: 75)]
    public string? LabelValidation { get; set; }

    [DefaultSettingValue("0")]
    [Range(1, 100)]
    public int GoalValidation { get; set; }
}

I want the attributes above each List to apply to the int and string types, respectively, inside them. Seeing that just doing something like:

[Required]
[StringLength(maximumLength: 75)]
public List<string?> LabelList { get; set; } = new List<string?>();

doesn't work, I made the LabelValidation and GoalValidation variables with the intention of using them in an HTML form where the user inputs values for labels and goals into the list like so:

<input asp-for="LabelList[ind]"  placeholder="@ViewBag.Chart.LabelList[ind]" value="@ViewBag.Chart.LabelList[ind]" />
<span asp-validation-for="LabelValidation" ></span>

<input asp-for="GoalList[ind]"  placeholder="@ViewBag.Chart.GoalList[ind]" value="@ViewBag.Chart.GoalList[ind]" />
<span asp-validation-for="GoalValidation" ></span>

but that does not seem to work either. How can I apply these attributes to the elements within the lists?

CodePudding user response:

Consider to use custom attributes for this purpose:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Reflection;

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class IntListValidationAttribute : ValidationAttribute
{
    public int Minimum { get; private set; }
    public int Maximum { get; private set; }

    public IntListValidationAttribute(string errorMessage, int minimum, int maximum)
        : base(errorMessage)
    {
        Minimum = minimum;
        Maximum = maximum;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var obj = validationContext.ObjectInstance;
        if (value is List<int> list)
        {
            PropertyInfo[] myPropertyInfo = obj.GetType().GetProperties();
            for (int i = 0; i < myPropertyInfo.Length; i  )
            {
                if (myPropertyInfo[i].PropertyType.Equals(typeof(List<int>)))
                {
                    foreach (var item in list)
                    {
                        if (item < Minimum || item > Maximum)
                        {
                            return new ValidationResult(ErrorMessage);
                        }
                    }
                    return ValidationResult.Success;
                }
            }
        }
        return new ValidationResult(ErrorMessage);
    }
}

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class StringListValidationAttribute : ValidationAttribute
{
    public int MaximumLength { get; private set; }

    public StringListValidationAttribute(string errorMessage, int maximumLength)
        : base(errorMessage)
    {
        this.MaximumLength = maximumLength;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var obj = validationContext.ObjectInstance;
        if (value is List<string> list)
        {
            PropertyInfo[] myPropertyInfo = obj.GetType().GetProperties();
            for (int i = 0; i < myPropertyInfo.Length; i  )
            {                   
                if (myPropertyInfo[i].PropertyType.Equals(typeof(List<string>)))                        
                {
                    foreach (var item in list)
                    {
                        if (item.Length > MaximumLength)
                        {
                            return new ValidationResult(ErrorMessage);
                        }
                    }
                    return ValidationResult.Success;
                }
            }
        }
        return new ValidationResult(ErrorMessage);
    }
}

And then apply the attributes to properties:

public class ChartModel
{        
    [IntListValidation("Validation error", minimum: 2, maximum: 99)]      
    public List<int> GoalList { get; set; } = new List<int>();

    [StringListValidation("Validation error", maximumLength: 15)]        
    public List<string> LabelList { get; set; } = new List<string>();
}
  • Related