Я считаю, что это довольно просто, я просто не могу найти правильный способ показать отображаемое имя для элемента в списке в моей модели.
Моя упрощенная модель:
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);
сломается, если нет имен. Есть ли здесь «лучший способ» получить здесь отображаемое имя?
c#
asp.net-mvc
razor
model
Jonesopolis
источник
источник
List<PersonNameViewModel>
вас естьIEnumerable<PersonNameViewModel>
, то можно также использовать выражениеmodel => model.Names.First().FullName
. Это правильно? Тем не менее, я думаю, что мне больше всего нравитсяdummyModel
пример из трех. В противном случае у вас может быть несколько свойств, которые вам нужно ввести или вставитьmodel.Names[0].
. Опять же, возможно, вам следует реорганизовать раздел до частичного представления, которое принимаетList
или вIEnumerable
качестве своей модели.FirstOrDefault()
работаю с пустым списком.Есть другой способ сделать это, и я думаю, он более понятен:
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>
источник
Мне нравится решение 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, например:
источник
DisplayNameFor
самом деле никогда не вызываетсяget
для свойства, поэтому не имеет значения, создаете ли вы экземпляр.В качестве альтернативного решения вы можете попробовать:
Он будет работать, даже если список пуст!
источник