2011-06-21 15 views
23

Bir [Zorunlu] özniteliği bir Liste <> özelliğine koymak mümkün mü?Genel Liste Özelliğinde Gerekli Özellik Özellik

POST'ta genel bir listeye bağlanıyorum ve özellik içinde 0 öğe varsa, ModelState.IsValid() başarısız olup olmadığını merak ediyordum?

+0

] (https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.minlengthattribute%28v=vs.110%29.aspx) – janv8000

cevap

27

Liste stili özelliğine Required özniteliğinin eklenmesi gerçekten istediğiniz şeyi yapmaz. Listenin oluşturulmadığı, ancak listenin içinde 0 öğe varsa, şikayetçi olmaz.

Ancak, kendi veri ek açıklamaları öznitelik türetmek için yeterli kolay ve böyle Count> 0. Something (henüz test) için listeyi kontrol yapmalıdır:

[AttributeUsage(AttributeTargets.Property)] 
public sealed class CannotBeEmptyAttribute : ValidationAttribute 
{ 
    private const string defaultError = "'{0}' must have at least one element."; 
    public CannotBeEmptyAttribute () : base(defaultError) // 
    { 
    } 

    public override bool IsValid (object value) 
    { 
     IList list = value as IList; 
     return (list != null && list.Count > 0); 
    } 

    public override string FormatErrorMessage (string name) 
    { 
     return String.Format(this.ErrorMessageString, name); 
    } 
} 

DÜZENLEME:

Ayrıca, listenizi görünümünüze nasıl bağladığınıza dikkat etmeniz gerekir. Örneğin, eğer böyle bir görüşe bir List<String> bağlamak:

<input name="ListName[0]" type="text" /> 
<input name="ListName[1]" type="text" /> 
<input name="ListName[2]" type="text" /> 
<input name="ListName[3]" type="text" /> 
<input name="ListName[4]" type="text" /> 

MVC modeli bağlayıcı olacak daima Listenizde 5 elemanları, bütün String.Empty koydu. Görünümünüz bu şekilde çalışıyorsa, özniteliğinizin genel tür parametresini çekmek ve her liste öğesini default(T) ya da bir şeyle karşılaştırmak için Yansıma'yı kullanma gibi biraz daha karmaşık olması gerekir.

JQuery'yi, girdi öğelerini dinamik olarak oluşturmak için daha iyi bir alternatif kullanmaktır. Minimalist örneklere arıyorsanız olanlar için

+0

Bu düzenlemeyi detaylandırabileceğinizi sanmıyorum (https://stackoverflow.com/questions/45201531/cant-force-listint-to-be-required)? – Sinjai

+0

Neyi sorduğumdan emin değilim ... bağlantın sadece bir soruya gidiyor. –

+0

Evet, soru (potansiyel olarak - bu kısmen soruyorum) ilgili. – Sinjai

20

:

[AttributeUsage(AttributeTargets.Property)] 
public sealed class CannotBeEmptyAttribute : RequiredAttribute 
{ 
    public override bool IsValid(object value) 
    { 
     var list = value as IEnumerable; 
     return list != null && list.GetEnumerator().MoveNext(); 
    } 
} 

Bu kabul edilen yanıt kodu değiştirilir. Sorudan ve hatta daha fazla durumda, System.Collections hiyerarşisinde IEnumerable'ın daha yüksek olması durumunda uygundur. Ek olarak, RequiredAttribute adlı davranışı devralır, dolayısıyla açıkça kodlamaya gerek yoktur. Eğer onay kutusu listesi varsa

Liste kutusunun içindeki Listesi için

Gerekli Doğrulama Özellik

İşte
[AttributeUsage(AttributeTargets.Property)] 
public sealed class CustomCheckBoxListRequiredAttribute : RequiredAttribute 
{ 
    public override bool IsValid(object value) 
    { 
     bool result = false; 

     var list = value as IEnumerable<CheckBoxViewModel>; 
     if (list != null && list.GetEnumerator().MoveNext()) 
     { 
      foreach (var item in list) 
      { 
       if (item.Checked) 
       { 
        result = true; 
        break; 
       } 
      } 
     } 

     return result; 
    } 
} 

benim Görünüm Modeli

benim gereksinimi için

Modifiye @moudrick uygulamasıdır

[AttributeUsage(AttributeTargets.Property)] 
public sealed class CustomListRequiredAttribute : RequiredAttribute 
{ 
    public override bool IsValid(object value) 
    { 
     var list = value as IEnumerable; 
     return list != null && list.GetEnumerator().MoveNext(); 
    } 
} 

+0

En Genel çözüm, Teşekkürler! –

1
public class CheckBoxViewModel 
{   
    public string Name { get; set; } 
    public bool Checked { get; set; } 
} 

Kullanımı kullananlar için

[CustomListRequiredAttribute(ErrorMessage = "Required.")] 
public IEnumerable<YourClass> YourClassList { get; set; } 

[CustomCheckBoxListRequiredAttribute(ErrorMessage = "Required.")] 
public IEnumerable<CheckBoxViewModel> CheckBoxRequiredList { get; set; } 
2

C# 6.0 ve kim biri gömlekleri arıyoruz: Eğer [MinLengthAttribute kullanabilirsiniz yerine List bir dizi kullanmak için modelinizi değiştirirseniz

[AttributeUsage(AttributeTargets.Property)] 
public sealed class CannotBeEmptyAttribute : RequiredAttribute 
{ 
    public override bool IsValid(object value) => (value as IEnumerable)?.GetEnumerator().MoveNext() ?? false; 
} 
İlgili konular