簡體   English   中英

DisplayNameFor() 來自列表<Object>在模型

[英]DisplayNameFor() From List<Object> in Model

我相信這很簡單,我似乎找不到正確的方法來顯示模型中列表中項目的顯示名稱。

我的簡化模型:

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

和名稱:

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

現在我想制作一個表格來顯示一個人的所有名字,並獲得DisplayNameFor FullName 明顯地,

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

行不通,而且

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

如果沒有名字就會中斷。 是否有“最佳方式”在此處獲取顯示名稱?

這實際上有效,即使列表中沒有項目:

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

它有效是因為 MVC 解析表達式而不是實際執行它。 這使它可以找到正確的屬性和屬性,而無需列表中的元素。

值得注意的是,甚至不需要使用參數(上面的model )。 這也有效:

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

就像這樣:

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

還有另一種方法可以做到這一點,我想這更清楚:

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

然后,在視圖中:

@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>

作為替代解決方案,您可以嘗試:

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

即使列表為空,它也會起作用!

我喜歡 T-moty 的解決方案。 我需要一個使用泛型的解決方案,所以我的解決方案本質上是這樣的:

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

在視圖中使用它與他的示例相同。 我創建了一個空對象的單個實例,因此每次引用Default時我都不會創建一個新實例。

請注意,需要new()約束才能調用new T() 如果您的模型類沒有默認構造函數,或者您需要向構造函數添加參數,則可以使用以下命令:

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

該視圖將有一個@model行,如:

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

在 ASP.NET Core 中, Html.DisplayNameForInnerType()解決了這個問題。 可以這樣使用:

Html.DisplayNameForInnerType((PersonNameViewModel person) => person.FullName)

請注意,必須在 lambda 表達式的參數中明確指定PersonNameViewModel類型。

這就是API 文檔必須說的:

如果當前模型表示集合,則返回指定表達式的顯示名稱。

它在當前Model本身是一個集合以及它的一個成員是一個集合時起作用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM