Мой Linq-SQL нарушает привязку модели MVC2?
Я пытаюсь обработать http-сообщение из веб-формы, используя встроенную привязку модели MVC 2s. Из того, что я искал последние несколько часов, я понял, что это немного привередливо к "объектам внутри объектов".
Я ищу любые ответы или ссылки на ресурсы, которые могут помочь мне понять это. Я все еще на ранних стадиях этого тоже, так что, если есть лучший способ - я все уши. Я сам писал Linq-SQL и не использовал генерацию кода. Я думаю, что самый близкий ответ, который я ищу, здесь, но я все еще не понимаю его.
Модель клиента (моя лучшая догадка, где проблема):
public class Client
{
public int ClientID { get; set; }
...
[Column(Name = "Address_id")]
internal int AddressID { get; set; }
internal EntityRef<Address> _address;
[System.Data.Linq.Mapping.Association(ThisKey = "AddressID", Storage = "_address")]
public Address Address
{
get { return _address.Entity; }
internal set { _address.Entity = value; AddressID = value.AddressID; }
}
}
Адрес модели (в пределах сущности клиента)
public class Address
{
[Column] public string Address1 { get; set; }
[Column] public string Address2 { get; set; }
[Column] public string City { get; set; }
...
Посмотреть модель:
public class ClientFormViewModel
{
public Client Client { get; set; }
...
}
Посмотреть:
<!-- id is hidden -->
<%: Html.EditorFor(m => m.Client.ClientID) %>
...
<%: Html.EditorFor(m => m.Client.Address.AddressID) %>
<%: Html.LabelFor(m => m.Client.Address.Address1) %>
<%: Html.EditorFor(m => m.Client.Address.Address1) %><br />
<%: Html.LabelFor(m => m.Client.Address.Address2) %>
<%: Html.EditorFor(m => m.Client.Address.Address2) %><br />
...
контроллер:
public ViewResult Edit(int clientId)
{
var client = clientsRepository.Clients.First(x => x.ClientID == clientId);
...
// create view model
var viewModel = new ClientFormViewModel
{
Client = client,
...
};
return View(viewModel);
}
[HttpPost]
public ActionResult Edit(ClientFormViewModel clientForm)
{
if (ModelState.IsValid)
{
clientsRepository.SaveClient(clientForm.Client);
return RedirectToAction("List");
}
else // validation error, so redisplay the same view
...
}
Поэтому моя проблема в том, что... когда я вхожу в действие HttpPost, clientForm.Client.Address всегда имеет значение null. Хотя, когда я смотрю на ModelState (который действителен) или использую Request.["Key"], все ключи соответствуют структуре моего объекта. Например, я вижу ModelState ["Client.Address.Address1"], "Client.Address.Address2" и т. Д.
Все остальные базовые свойства заполнены в порядке, что заставляет меня думать, что код linq-sql нарушает привязку модели. Но как? И есть ли способ это исправить? Если эти ключи находятся в словаре Request/ModelState, почему они не отображаются на объект? Я что-то упускаю из виду?
2 ответа
После того, как @Darin Dimitrov упомянул об использовании модели представления вместо прохождения модели предметной области (что, как я думал, я уже делал), я решил найти решение.
Вместо того, чтобы полагаться на привязку модели по умолчанию для получения моего сопоставления Linq-SQL, я создал модель плоского представления.
Больше всего мне помогли эти два поста:
http://geekswithblogs.net/michelotti/archive/2009/10/25/asp.net-mvc-view-model-patterns.aspx
http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/
Сначала у меня были некоторые проблемы с AutoMapper, но теперь он работает довольно хорошо. Я бы порекомендовал это!
Address
сеттер должен быть public
если вы хотите, чтобы связыватель модели мог успешно связать его:
internal EntityRef<Address> _address;
[System.Data.Linq.Mapping.Association(ThisKey = "AddressID", Storage = "_address")]
public Address Address
{
get { return _address.Entity; }
set { _address.Entity = value; AddressID = value.AddressID; }
}
Лично я бы порекомендовал вам использовать модели представления вместо передачи этих моделей в представления и из них.