Modeldeki <Nesne> Listesinden DisplayNameFor ()


88

Bunun oldukça basit olduğuna inanıyorum, modelimdeki bir listedeki bir öğenin görünen adını göstermenin doğru yolunu bulamıyorum.

Basitleştirilmiş modelim:

public class PersonViewModel
{
    public long ID { get; set; }

    private List<PersonNameViewModel> names = new List<PersonNameViewModel>();

    [Display(Name = "Names")]
    public List<PersonNameViewModel> Names { get { return names; } set { names = value; } }      
}

ve İsimler:

public class PersonNameViewModel
{
    public long ID { get; set; }

    [Display(Name = "Set Primary")]
    public bool IsPrimary { get; set; }

    [Display(Name = "Full Name")]
    public string FullName { get; set; }
}

Şimdi, bir kişi için tüm isimleri gösteren bir tablo yapmak ve FullName İçin DisplayName'i almak istiyorum. Açıkçası,

@Html.DisplayNameFor(model => model.Names.FullName);

işe yaramazdı ve

@Html.DisplayNameFor(model => model.Names[0].FullName);  

isim yoksa kırılır. Burada görünen adı almanın 'en iyi yolu' var mı?

Yanıtlar:


144

Bu, listedeki öğeler olmasa bile gerçekten çalışır:

@Html.DisplayNameFor(model => model.Names[0].FullName)

Çalışır çünkü MVC ifadeyi gerçekten yürütmek yerine ayrıştırır. Bu, listede bir öğe olmasına gerek kalmadan doğru özelliği ve niteliği bulmasını sağlar.

Parametrenin ( modelyukarıda) kullanılmasına bile gerek olmadığını belirtmek gerekir. Bu da işe yarar:

@Html.DisplayNameFor(dummy => Model.Names[0].FullName)

Bunun yaptığı gibi:

@{ Namespace.Of.PersonNameViewModel dummyModel = null; }
@Html.DisplayNameFor(dummyParam => dummyModel.FullName)

Bir yerine bir List<PersonNameViewModel>sahipseniz IEnumerable<PersonNameViewModel>, ifadeyi kullanmanın da güvenli olduğunu varsayıyorum model => model.Names.First().FullName. Bu doğru mu? Bununla dummyModelbirlikte, üçünün en iyi örneğini sevdiğimi düşünüyorum . Aksi takdirde, yazmanız veya yapıştırmanız gereken birkaç özelliğiniz olabilir model.Names[0].. Daha sonra, belki de bölümü modelini Listveya IEnumerablemodelini kabul eden kısmi bir görünüme yeniden düzenlemelisiniz .
aaaantoine

6
Test ettim ve FirstOrDefault()boş bir liste ile çalışıyor.
Josh K

Maalesef bu, IEnumerable özelliği üzerinde çalışmaz.
Willy David Jr

7

Bunu yapmanın başka bir yolu var ve sanırım bu daha açık:

public class Model
{
    [Display(Name = "Some Name for A")]
    public int PropA { get; set; }

    [Display(Name = "Some Name for B")]
    public string PropB { get; set; }
}

public class ModelCollection
{
    public List<Model> Models { get; set; }

    public Model Default
    {
        get { return new Model(); }
    }
}

Ve sonra görünümde:

@model ModelCollection

<div class="list">
    @foreach (var m in Model.Models)
    {
        <div class="item">
            @Html.DisplayNameFor(model => model.Default.PropA): @m.PropA
            <br />
            @Html.DisplayNameFor(model => model.Default.PropB): @m.PropB
        </div>
    }
</div>

3

Alternatif bir çözüm olarak şunları deneyebilirsiniz:

@Html.DisplayNameFor(x => x.GetEnumerator().Current.ItemName)

Liste boş olsa bile çalışacaktır!


Tim S'nin çözümü yerine neden bu çözümü kullanmalıyım?
EKanadily

1

T-moty'nin çözümünü beğendim. Jenerik kullanan bir çözüme ihtiyacım vardı, bu yüzden çözümüm esasen şu:

public class CustomList<T> : List<T> where T : new()
{       
    public static async Task<CustomList<T>> CreateAsync(IQueryable<T> source)
    {           
        return new CustomList<T>(List<T> list); //do whatever you need in the contructor, constructor omitted
    }

    private T defaultInstance = new T();

    public T Default
    {
        get { return defaultInstance; }
    }
}

Bunu görünümde kullanmak onun örneğiyle aynıdır. Ben yeni bir örneğini her zaman referans oluşturarak değilim bu yüzden boş bir nesnenin tek bir örneğini oluşturmak Varsayılan .

Yeni T () ' yi çağırmak için yeni () kısıtlamasının gerekli olduğuna dikkat edin . Model sınıfınızın varsayılan bir kurucusu yoksa veya kurucuya argümanlar eklemeniz gerekiyorsa, bunu kullanabilirsiniz:

private T defaultInstance = (T)Activator.CreateInstance(typeof(T), new object[] { "args" });

Görünümde aşağıdaki gibi bir @model satırı olacaktır :

@model CustomList<Namespace.Of.PersonNameViewModel.Model>

Not DisplayNameForgerçekte hiçbir zaman çağrıları getEğer bir örneğini oluşturmanız, önemli değil bu yüzden, özellik için.
NetMage
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.