Я сделал этот пост более года назад, и я думаю, что имеет смысл обновить его, так как он получает довольно много просмотров.
Я либо что-то упустил, либо Microsoft действительно испортила MVC. Я работал над проектами Java MVC, и они были чистыми и простыми. Это, однако, полный беспорядок ИМО. Примеры онлайн, такие как NerdDinner и проекты, обсуждаемые на ASP.Net, слишком просты, поэтому они «просто» работают. Извините, если это звучит отрицательно, но это мой опыт до сих пор.
У меня есть хранилище и служба, которая общается с хранилищем. Диспетчеры звонят в сервис.
Мой уровень данных НЕ является постоянным, так как классы были сгенерированы SQL metal. Из-за этого у меня много ненужного функционала. В идеале я хотел бы иметь POCO, но я еще не нашел хорошего способа добиться этого.
* Обновление: Конечно, Microsoft ничего не испортила - я сделал. Я не полностью понимал инструменты, которые были в моем распоряжении. Основным недостатком того, что я сделал, было то, что я выбрал неправильную технологию для сохранения своих сущностей. LINQ to SQL хорошо работает в приложениях с отслеживанием состояния, поскольку контекст данных можно легко отслеживать. Тем не менее, это не относится к ситуации без гражданства. Какой будет правильный выбор? Сначала код Entity Framework или только код работают довольно хорошо, но что более важно, это то, что это не должно иметь значения. MVC или приложения переднего плана не должны знать, как хранятся данные. *
При создании объектов я могу использовать привязку объектов:
[HttpPost]
public ActionResult Create(Customer c)
{
// Persistance logic and return view
}
Это прекрасно работает, MVC делает некоторую привязку за сценой, и все "очень хорошо".
Это не было "Jolly Good". Заказчиком была модель предметной области, и, что еще хуже, она зависела от среды персистентности, потому что она была сгенерирована SQL metal. Что бы я сделал сейчас, это разработал модель моей предметной области, которая была бы независимой от хранилищ данных или уровней представления. Затем я создал бы модель представления из моей доменной модели и использовал бы ее вместо этого.
Как только я бы хотел сделать что-то более сложное, например, - сохранить заказ, который связан с клиентом, все кажется сломанным:
[HttpPost]
public ActionResult Create(Order o)
{
// Persistance logic and return view
}
Чтобы сохранить заказ, мне нужен Customer или хотя бы CustomerId. CustomerId присутствовал в представлении, но к тому времени, когда он получил метод Create, он потерял CustomerId. Мне не нравится сидеть без дела при отладке кода MVC, так как я не смогу изменить его в среде хостинга в любом случае.
Хорошо, немного стону здесь, извините. Что бы я сделал сейчас, это создаю модель представления под названием NewOrder, или SaveOrder, или EditOrder, в зависимости от того, чего я пытаюсь достичь. Эта модель представления будет содержать все интересующие меня свойства. Автоматическое связывание из коробки, как следует из названия, будет связывать отправленные значения и ничего не будет потеряно. Если мне нужно нестандартное поведение, я могу реализовать свое собственное «связывание», и оно выполнит эту работу.
Альтернативой является использование FormCollection:
[HttpPost]
public ActionResult Create(FormCollection collection)
{
// Here I use the "magic" UpdateModel method which sometimes works and sometimes doesn't, at least for LINQ Entities.
}
Это используется в книгах и учебных пособиях, но я не вижу смысла в методе, у которого есть альтернатива: TryUpdateModel - если этот сбой или модель недействительны, он пытается обновить ее в любом случае. Как вы можете быть уверены, что это сработает?
Автосвязывание с моделями вида будет работать большую часть времени. Если это не так, то вы можете переопределить это. Как вы знаете, это всегда будет работать? Вы тестируете его и хорошо спите.
Другой подход, который я попробовал, - это использование ViewModel - объектов-обёрток с правилами валидации. Это звучит как хорошая идея, за исключением того, что я не хочу добавлять аннотации к классам сущностей. Этот подход отлично подходит для отображения данных, но что вы делаете, когда дело доходит до записи данных?
[HttpPost]
public ActionResult Create(CustomViewWrapper submittedObject)
{
// Here I'd have to manually iterate through fields in submittedObject, map it to my Entities, and then, eventually, submit it to the service/repository.
}
** Просмотр модели - хороший путь вперед. Должен быть некоторый код отображения из модели представления в модель предметной области, который затем может быть передан в соответствующую службу. Это не правильный путь, но это один из способов сделать это. Инструменты автоматического картирования - ваши лучшие друзья, и вы должны найти тот, который соответствует вашим требованиям, в противном случае вы будете писать тонны шаблонного кода. **
Я что-то упустил или Microsoft MVC3 должен работать таким образом? Я не понимаю, как это упрощает вещи, особенно в сравнении с Java MVC.
Извините, если это звучит негативно, но это мой опыт. Я ценю тот факт, что фреймворк постоянно совершенствуется, внедряются такие методы, как UpdateModel, но где документация? Может быть, пора остановиться и немного подумать? Я предпочитаю, чтобы мой код был непротиворечивым, но, как я уже видел, я не уверен, что это верный путь вперед.
Я люблю рамки. Есть так много, чтобы узнать, и это не намного интереснее, чем когда-либо. Вероятно, следует сделать еще один пост, касающийся веб-форм. Я надеюсь, что это полезно.