10

After updating the suggestion I'm still getting the error

Tried both with .SingleOrDefault() or FirstOrDefault()

enter image description here

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; }
}
Community
  • 1
  • 1
Nick Kahn
  • 19,652
  • 91
  • 275
  • 406

5 Answers5

11

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;
  }
Nick Kahn
  • 19,652
  • 91
  • 275
  • 406
  • 1
    Today you can use the generic version of GetCustomAttributes: `typeof(EmployeeViewModel).GetProperty(name).GetCustomAttributes().SingleOrDefault()` – user1127860 Sep 24 '20 at 08:27
  • @user1127860 - I don't think that's true, unless I'm doing something wrong. When I try to call GetCustomAttributes with type arguments, the compiler gets mad at me. – David Apr 05 '23 at 23:56
2

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;
Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
0

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; }
}
heymega
  • 9,215
  • 8
  • 42
  • 61
0
var maxLength = typeof(EmployeeViewModel)
                    .GetProperty("Name")
                    .GetCustomAttributes<StringLengthAttribute>()
                    .FirstOrDefault()
                    .MaximumLength;
Andriy Tolstoy
  • 5,690
  • 2
  • 31
  • 30
0

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; }
}
Richard Griffiths
  • 758
  • 1
  • 11
  • 23