2011-12-28 2 views
0

Я потратил последние 2 дня, пытаясь понять это, в основном у меня есть две модели (Event и EventStyle), но EventStyle не привязывается ни к чему, как я пытаюсь.MVC3 Model Binding с внешними ключами

Эти классы являются частью базы данных Code-First, а модель Event имеет внешний ключ для EventStyle.

Вот моя разбавленная модель:

public class Event { 
    public string Id { get; set; } 
    public string Name { get; set; }  
    public string Description { get; set; } 
    public virtual EventStyle Style { get; set; } 
} 

public class EventStyle { 
    public string Id { get; set; } 
    public string Image { get; set; } 
} 

В моем контроллере у меня есть это:

[HttpPost] 
public ActionResult Create(Event evt) { /* add evt to the database */ } 

и простой вид:

@using (Html.BeginForm()) { 
    @Html.HiddenFor(evt => evt.Id) 
    @Html.HiddenFor(evt => evt.Style) 
    @Html.TextBoxFor(evt => evt.Name) 
    @Html.TextAreaFor(evt => evt.Description) 
} 

(я на самом деле есть custom @ Html.EditorFor для evt.Style, который изменяет значение скрытого поля)

Когда форма отправлена, событие правильно привязано к Id, Name и Description. Однако свойство Style остается равным null, даже если поле Hidden содержит действительный идентификатор EventStyle в базе данных.

Если удалить скрытые поля, то стиль становится одним по умолчанию (как указано в конструкторе мероприятия)

Я также попытался с помощью ModelBinder на EventStyle, но правильный Id никогда не приходит через bindingContext, это может быть часть проблемы.

Однако правильный идентификатор поступает через Binder controllerContext или напрямую с помощью FormCollection в контроллере. Я бы предпочел лучше работать с ModelBinding.

Возможно, ModelBinder не имеет никаких знаний о моей базе данных? Если да, то как я могу заставить его распознать мою базу данных?

EDIT: хмм просто убрали virtual и теперь Binder набирает правильный Id из формы, но она по-прежнему не получают модели Event

edit2: решить, используя эту функцию, чтобы загрузить EventStyle из база данных:

if (evt.Style != null) { 
    evt.Style = db.EventStyles.Find(evt.Style.Id); 
} 

ответ

0

Используйте само свойство Id:

@Html.HiddenFor(evt => evt.Style.Id) 

Редактировать

Что-то следует отметить, что @html.[InputType]For() вспомогательные методы есть установить соответствующие атрибуты name/id для элементов в разметке, чтобы при их отправке связующее устройство по умолчанию узнало, как установить свойства в вашей модели.

Если вы посмотрите на HTML-разметки, вы увидите свой элемент стиля создается следующим образом:

<input id="Style_Id" type="hidden" value="" name="Style.Id" /> 

Это соглашение об именовании, что модель по умолчанию Связыватель понимает и то, что он использует, чтобы установить свойства вашей модели.

+0

huh Я пропустил это, кажется, работает, спасибо! , однако, он не загружает идентификатор из базы данных. Должен ли я сделать это вручную через 'event.Style.Id'? – Jorticus

+0

@Jorticus по умолчанию modelbinder не знает базы данных, цель состоит в том, чтобы просто установить свойства на вашей модели, которые находятся в Params. Не рекомендуется указывать знания базы данных модели. – Craig

0

Скрытое поле может хранить только скалярные значения. Ваш класс EventStyle является сложным и состоит из 2-х свойств. Так что вам нужно 2 скрытых полей для каждого из 2-х свойств:

@Html.HiddenFor(evt => evt.Style.Id) 
@Html.HiddenFor(evt => evt.Style.Image) 
+0

спасибо! просто увидел то же самое ниже. Свойство Image фактически вытащится из базы данных, у меня есть отдельный редактор для редактирования EventStyles. – Jorticus

0

Вам не хватает свойства EventStyle в классе модели событий, чтобы сделать его внешним ключом для этой модели.

Просто добавьте это в свой класс моделей Event, и все должно быть в порядке.

public int EventStyleId { get;set; } 
Смежные вопросы