#c# #asp.net-mvc #reflection #asp.net-mvc-3
#c# #asp.net-mvc #отражение #asp.net-mvc-3
Вопрос:
При возврате строго типизированных моделей для таких представлений, как Create и Edit (когда проверка объекта, который мы редактируем, завершается неудачей) Обычно я готовлю модели следующим образом:
//
// GET: /Invoice/Create
public virtual ActionResult Create()
{
// prepare the empty model
Invoice model = new Invoice();
model.Client = new Client();
model.Client.PostCode = new PostCode();
return View(model);
}
//
// POST: /Invoice/Create
[HttpPost]
public virtual ActionResult Create(Invoice document,
FormCollection collection)
{
// check for errors
if (!ViewData.ModelState.IsValid)
{
document.Client = new Client();
document.Client.PostCode = new PostCode();
return View(document);
}
Теперь я знаю, что другие делают то же самое, фактически вы можете увидеть этот же подход в примере MVC Music Store и других. Однако это очень подвержено ошибкам, поскольку можно случайно пропустить объект, на который требуется ссылка в представлении. Это также требует слишком много размышлений о взаимодействии представления и модели. Чего бы я хотел, так это какого-то автоматизма. Свойства, введенные со значением в моделях, обычно не являются проблемой, поскольку по умолчанию они равны нулю или пустым строкам. Ссылочные типы, однако, следует инициализировать с помощью new
.. но рано или поздно мы получаем повторяющиеся блоки кода, свойства ссылочного типа не учитываются и т.д. И я не думаю, что это хорошая практика кодирования.
Какие еще варианты мы могли бы использовать?
Обновить:
Поскольку ответы вроде как упустили суть (они никоим образом не освобождают нас от размышлений о моделях и требуют дополнительного кода в классах моделей), я подумал, сработает ли этот вариант:
- Используйте пользовательский фильтр действий,
- переопределение
OnActionExecuted()
- используйте отражение внутри этого метода, чтобы извлечь объект из модели, перечислить его общедоступные свойства и попытаться их инициализировать.
У меня частично реализованы шаги 1, 2 и 3, но я не могу понять, как это сделать «… = новый клиент(); » программно с отражением.
Ответ №1:
Сделайте так, чтобы свойства вашей модели возвращали новый экземпляр, если он равен null
private Client client;
public Client Client
{
get
{
if (client == null)
client = new Client();
return client;
}
}
Ответ №2:
Я предлагаю вам использовать строго типизированное представление, привязанное к ViewModel, отличное от модели предметной области, которую вы пытаетесь создать, и поместить любую необходимую логику в конструктор ViewModel
Ответ №3:
Я не уверен, что полностью понимаю ваш вопрос. Вы хотите автоматизировать что? ViewModels и представления? Вы создаете строго типизированные представления?
Я создал шаблон T4, который я указываю на базу данных, и он генерирует ViewModel для каждой таблицы. Внешние ключи становятся выпадающими списками, длинные строки получают текстовое поле вместо текстового поля и т.д. Затем я удаляю те, которые мне не нужны, и изменяю те, которые хочу сохранить. Это не полностью автоматизированный процесс, но он выполняет от 80 до 90 процентов работы, в зависимости от проекта.
Затем я генерирую строго типизированные представления из этих ViewModels.
Также похоже, что вас может заинтересовать AutoMapper.