2015-04-23 65 views
5

的StringLength更新建议后,我仍然得到错误如何从DataAnnotations

都尝试用.SingleOrDefault()FirstOrDefault()

enter image description here

我需要检索StringLength标注值,在这里是我的代码,但我发现了以下错误。

我试图实现几乎从here相同的代码,但得到的错误:

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; 
     } 
    } 

//电话:

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; } 
} 

回答

4

我能想通,测试其工作的伟大,在情况下,如果其他人正在寻找!

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

你可以从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()答案。

所以你需要使用SingleOrDefault()尝试,而不是像Single()

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

如果你有'MinimumLength = 1',那么你正在执行有最小长度?即使这些字段是可选的? –

+0

@AbuHamzah: - 更新我的答案。请检查! –

+0

我更新了我的问题,仍然得到同样的错误 –

0

你想显示长度为错误消息的一部分?如果是这样,我相信你可以把...

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

没有,我使用其他验证目的的长度,但不放映长度错误信息 –

0
var maxLength = typeof(EmployeeViewModel) 
        .GetProperty("Name") 
        .GetCustomAttributes<StringLengthAttribute>() 
        .FirstOrDefault() 
        .MaximumLength; 
0

正如我刚刚解决这个,我想我会提供LinqPad码我和玩弄。这是完全够的Linqpad运行,只是如果你想探索增加进口。

记下我的评论,你真正需要的位。我发现它非常棘手有时没有一些背景适应代码。

///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; } 
}