2009-02-27 2 views
12

Я хочу получить некоторую привязку, работающую в моем приложении mvc. Я обнаружил, что вложенные свойства автоматически не связаны связующим устройством по умолчанию в RC1-выпуске asp.net mvc. У меня есть следующий класс структуру:Модель привязки вложенных свойств в asp.net mvc

public class Contact{ 
    public int Id { get; set; } 
    public Name Name { get; set; } 
    public string Email { get; set; } 
} 

Где Name определяется как:

public class Name{ 
    public string Forename { get; set; } 
    public string Surname { get; set; } 
} 

Моя точка зрения определяется по линиям:

using(Html.BeginForm()){ 
    Html.Textbox("Name.Forename", Model.Name.Forename); 
    Html.Textbox("Name.Surname", Model.Name.Surname); 
    Html.Textbox("Email", Model.Email); 
    Html.SubmitButton("save", "Save"); 
} 

Мои действия контроллера определяется как:

public ActionResult Save(int id, FormCollection submittedValues){ 
    Contact contact = get contact from database; 
    UpdateModel(contact, submittedValues.ToValueProvider()); 

    //at this point the Name property has not been successfully populated using the default model binder!!! 
} 

Объект Email успешно связан, но не Name.Forename или Name.Surname. Может ли кто-нибудь сказать, должно ли это работать с использованием привязки модели по умолчанию, и я делаю что-то неправильно или если это не работает, и мне нужно свернуть собственный код для привязки вложенных свойств к объектам модели?

ответ

9

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

public ActionResult Save(int id) 
{ 
    Contact contact = db.Contacts.SingleOrDefault(c => c.Id == id); 

    UpdateModel(contact, new string[] { "Email" }); 
    string[] whitelist = new string[] { "Forename", "Surname" }; 
    UpdateModel(contact.Name, "Name", whitelist); 
} 
+0

Это отлично работает, спасибо tvanfosson. – 2009-02-27 13:14:31

+0

SingleOrDefault можно напрямую вызывать с выражением lamda –

+0

@PhilippM вы абсолютно правы, обновлены! – tvanfosson

4

Вот очень интересно, потому что если вы сделали

public ActionResult Save(int id, Contact contact) 
{ 
    //contact here would contain the nested values. 
} 

Я использую это с большим успехом. Полагаю, тогда вы могли бы как-то синхронизировать два объекта Contact вместе.

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

3

Чтобы связать имя, а не всю модель представления в POST, необходимо проинструктировать связующее устройство модели, что префикс будет использоваться. Это делается с использованием BindAttribute.

public ActionResult AddComment([Bind(Prefix = "Name")] Name name) 
{ 
    //do something 
} 
Смежные вопросы