Должен ли я иметь как текст, так и значение в моей модели для свойства, выбранного из выпадающего списка

#asp.net-mvc-4 #properties #model

#asp.net-mvc-4 #свойства #Модель

Вопрос:

В ASP.NET Приложение MVC У меня есть модель с именем CarSearchCriteria:

 public class CarSearchCriteria{
   public int CarMake {get;set;} // This is selected from a dropdownlist
   public int YearOfFirstReg {get;set;}
   public string ModelVariant {get;set}      

}
  

У меня есть два представления — одно для редактирования, а другое для просмотра. В представлении редактирования для свойства CarMake я могу сделать следующее. Я знаю, что мог бы использовать DropDownListFor, но пока не хотел связываться с SelectList:

 <select name="CarMake">
  <option value="1">BMW</option>
  <option value="2">Mercedes</option>
  <option value="3">Toyota</option>
</select>
  

Таким образом, механизм привязки модели легко свяжет выбранное значение с соответствующим свойством модели. Но как насчет режима чтения. Я не могу показать 1 или 2. Мне нужно показать BMW, Mercedes и так далее. Мой вопрос в том, какой предпочтительный способ, должен ли я иметь имя свойства, которое содержит фактическую текстовую информацию, что-то вроде CarMakeText?

Ответ №1:

У вас может быть как идентификатор (который у вас есть в данный момент), так и сам Make объект. К последнему никогда не нужно будет обращаться при построении модели, но к нему можно получить доступ при чтении модели. Свойство, доступное только для чтения с отложенной загрузкой, часто хорошо подходит для этого. Что-то вроде этого:

 public int CarMakeID { get; set; }

public Make CarMake
{
    get
    {
        if (CarMakeID == default(int))
            return null;
        // fetch the Make from data and return it
    }
}
  

Естественно, это во многом зависит от того, что такое a Make на самом деле и где вы его получаете. Если где-то есть только какой-то список в памяти, то это должно работать нормально. Если извлечение экземпляра a Make — это немного больше операции (скажем, извлечение из базы данных), тогда, возможно, потребуется некоторое кэширование внутри объекта на случай, если вам потребуется получить к нему доступ более одного раза:

 public int CarMakeID { get; set; }

private Make _carMake;
public Make CarMake
{
    get
    {
        if (CarMakeID == default(int))
            return null;
        if (_carMake == null)
            // fetch the Make from data and save it to _carMake
        return _carMake;
    }
}
  

Ответ №2:

Решение Дэвида просто отлично, но по какой-то причине я нахожу свое собственное решение, которое лучше соответствует моим потребностям, и, кроме того, я нахожу его более элегантным. Итак, в основном, что я делаю, я создаю класс, который содержит текстовые описания всех свойств, которые сохраняют только ID. Например, у меня есть следующая модель:

  public class EmployeeModel{
    public int EmployeeID {get;set;}
    public string FullName {get;set}
    *public int DepartmentID {get;set}
    *public int SpecialityID {get;set;}
    public int Age {get;set;}
 }
  

Свойства, отмеченные звездочкой, — это свойства, которые содержат идентификаторы возможных множества предопределенных параметров, и при показе мы должны показывать фактические описания, а не числовые представления. Итак, для этой цели мы создаем отдельный класс:

 public class EmployeeTextValues{
    public string DepartmentName {get;set;}
    public string SpecialityName {get;set;}
}
  

А затем я просто добавляю этот класс в качестве свойства в свою модель:

 public EmployeeTextValues TextValues {get;set;}
  

После этого к нему довольно легко получить доступ из любого места, включая Razor.

PS Я уверен, что многие люди будут стремиться выполнить следующее перед инициализацией этого свойства:

  Employee emp=new Employee;
 emp.Age=25;
 emp.TextValues.DepartmentName="Engineering";// Don't do this
  

Если вы попытаетесь получить доступ или установить текстовые значения.Вы получите Object reference not set to an instance of an object Someproperty . Поэтому не забудьте сначала установить текстовые значения для некоторого инициализированного объекта. Просто доброе напоминание, вот и все.