简体   繁体   中英

How to get the StringLength from DataAnnotations

After updating the suggestion I'm still getting the error

Tried both with .SingleOrDefault() or FirstOrDefault()

在此输入图像描述

I need to retrieve the StringLength annotation value and here is my code but I'm getting the following error.

I have tried to implement pretty much the same code from here but getting the error:

Sequence contains no elements

    public static class DataAnnotation
    {
        public static int GetMaxLengthFromStringLengthAttribute(Type modelClass, string propertyName)
        {
            int maxLength = 0;
            var attribute = modelClass.GetProperties()
                            .Where(p => p.Name == propertyName)
                            .Single()
                            .GetCustomAttributes(typeof(StringLengthAttribute), true)
                            .Single() as StringLengthAttribute;

            if (attribute != null)
                maxLength = attribute.MaximumLength;

            return 0;
        }
    }

//calling:

int length = DataAnnotation.GetMaxLengthFromStringLengthAttribute(typeof(EmployeeViewModel), "Name");


public class EmployeeViewModel
{         
    [StringLength(20, ErrorMessage = "Name cannot be longer than 20 characters.")] 
    public string Name{ get; set; }
}

I able to figured out, tested and its working great, in case if anybody else is looking!

  StringLengthAttribute strLenAttr = typeof(EmployeeViewModel).GetProperty(name).GetCustomAttributes(typeof(StringLengthAttribute), false).Cast<StringLengthAttribute>().SingleOrDefault();
  if (strLenAttr != null)
  {
     int maxLen = strLenAttr.MaximumLength;
  }

You can get the answer from When you get theLINQ Error “Sequence contains no elements”, this is usually because you are using the First() or Single() command rather than FirstOrDefault() and SingleOrDefault() .

So you need to try using SingleOrDefault() instead of Single() like

var attribute = modelClass.GetProperties()
                            .Where(p => p.Name == propertyName)
                            .SingleOrDefault()
                            .GetCustomAttributes(typeof(StringLengthAttribute), true)
                            .SingleOrDefault() as StringLengthAttribute;

Are you trying to show length as part of the error message? If so I believe you can just put...

public class EmployeeViewModel
{         
    [StringLength(20, ErrorMessage = "{0} cannot be longer than {1} characters.")] 
    public string Name{ get; set; }
}
var maxLength = typeof(EmployeeViewModel)
                    .GetProperty("Name")
                    .GetCustomAttributes<StringLengthAttribute>()
                    .FirstOrDefault()
                    .MaximumLength;

As I was just tackling this, I thought I'd provide the LinqPad code I'm playing around with. It is complete enough to run in Linqpad, just add the imports if you want to explore.

Note where I comment the bit you actually need. I've found it tricky sometimes to adapt code without some context.

///The rest of the code given as context as I'm working on a T4 template to create Model classes from Datalayer classes, so the iteration is required in my case
void Main()
{
    CVH p = new CVH();
    Type t = p.GetType();

    foreach (PropertyInfo prop in t.GetProperties()) //Iterating through properties
    {
        foreach (var facet in prop.GetCustomAttributes()) //Yank out attributes
        {
        //The bit you need
            if ((Type)facet.TypeId == typeof(StringLengthAttribute)) //What type of attribute is this? 
            {
                StringLengthAttribute _len = (StringLengthAttribute)facet; //Cast it to grab Maximum/MinimumLengths etc.
                Console.WriteLine($"My maximum field length is { _len.MaximumLength}");
                //End of the bit you need
                Console.WriteLine(_len.MinimumLength);              
            }
        }
    }
}
///Test class with some attributes
public class CVH
{
    [StringLength(50)]
    [DataType(DataType.PhoneNumber)]
    public string phone_1 { get; set; }
    [Required(ErrorMessage = "id is required")]
    public int id { get; set; }
    [Required(ErrorMessage = "id is required")]
    public int contact_id { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM