2015-04-23 38 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; } 
}