1

Я разрабатываю небольшое приложение, чтобы лучше понять, как работает MVC3 anda Razor. Я использую MVC3, весь код генерировался автоматически (dbContext через T4, Controller через Add Controller, Databese из модели EDMX ...).DropDownlistFor Создание нового объекта с MVC3

В моей модели у меня есть эта простая модель: http://i.stack.imgur.com/nyqu4.png

public partial class Application 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 

    public virtual ApplicationType ApplicationType { get; set; } 
} 

public partial class ApplicationType 
{ 
    public int Id { get; set; } 
    public string Type { get; set; } 
} 

Как вы можете видеть, ApplicationType в основном перечисление (жаль, что EF 4 не имеет поддержки перечислений). Так, в моем ApplicationController у меня есть это:

public ActionResult Create() 
{ 
    ViewBag.AppTypes = new SelectList(db.ApplicationTypes.OrderBy(c => c.Type), "Id", "Type"); 
    return View(); 
} 

[HttpPost] 
public ActionResult Create(Application application) 
{ 
    if (ModelState.IsValid) 
    { 
     db.Applications.Add(application); 
     db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 

    return View(application); 
} 

И на мой взгляд:

@Html.DropDownListFor(model => model.ApplicationType.Id, (SelectList)ViewBag.AppTypes, "Choose...") 

Теперь я столкнулся с двумя проблемами:

1) ApplicationType не заселенных:

As @ Html.DropDownListFor делает только простой выбор, он заполняет ID, но не заполняет свойство Type, как вы можете видеть ниже (извините, я могу " т разместить изображения, как я здесь новый):

http://i.stack.imgur.com/96IR1.png

На картинке вы можете увидеть, что идентификатор нормально, но тип пуст.

Что я делаю неправильно?

2) Дублирование данных

Вторая проблема заключается в том, что если я заполняю свойство Type вручную во время отладки (имитируя правильный сценарий рабочего процесса), ApplicationType будет дублироваться в базе данных, а не только со ссылкой на старый реестр.

Итак, как я могу сделать @ Html.DropDownListFor ссылаться на предыдущий существующий элемент вместо создания нового?

Благодарим за помощь!

ответ

0

Я считаю, что ошибка, которую вы делаете, заключается в использовании ваших моделей домена в представлении и при условии, что на почте вся модель должна быть полностью привязана и готова к хранению в базе данных. Хотя можно использовать модели домена в представлении, лучше всего создать отдельный файл Посмотреть модели.

Например:

public class ApplicationViewModel 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 

    public SelectList ApplicationTypeList { get; set; } 
    public string ApplicationTypeId { get; set; } 
} 

На ваш взгляд:

@Html.DropDownListFor(model => model.ApplicationTypeId, Model.ApplicationTypeList , "Choose...") 

В контроллере

[HttpPost] 
public ActionResult Create(ApplicationViewModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     Application application = new Application() 
     { 
      Id = model.Id, 
      Name = model.Name, 
      ApplicationType = db.ApplicationTypes 
       .First(a => a.Id == model.ApplicationTypeId); 

     }; 
     db.Applications.Add(application); 
     db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 

    return View(model); 
} 

Вы можете сделать проверку, что ApplicationTypeId ваш взгляд с моделью соответствует реальному применению введите часть проверки вашего модельного состояния. Вы можете использовать AutoMapper, чтобы ускорить процесс преобразования моделей просмотра в модели домена.

+0

Удивительно! Поэтому моя проблема была не в самом коде, а в том, как работает MVC. Это было легко понять и следовать. –

+0

Кстати, я использовал другой подход: общественного ActionResult Создать (приложение Application) { если (ModelState.IsValid) { INT appTypeID = Convert.ToInt32 (ModelState [ "ApplicationType.Id"] значение.. AttemptedValue); application.ApplicationType = db.ApplicationTypes.Single (s => s.Id == appTypeID); Я был расстроен этим обходным путем ... –

0

Вы пробовали:

@Html.DropDownListFor(model => model.ApplicationType.Id, m => m.ApplicationType.Type, "Choose...") 

Обратите внимание на второй параметр изменения.

+0

Спасибо, @mirezus! К сожалению, он не работает, поскольку второй параметр ожидает , а не лямбда. –

+0

О, это верно. Обычно вы можете обернуть элемент в строку selectlistitem, например: new SelectListItem {Text = m.TextToUse, Data = m.DataToUse} – mirezus

Смежные вопросы