Подготовка моделей для ASP.NET Представления MVC

#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 .. но рано или поздно мы получаем повторяющиеся блоки кода, свойства ссылочного типа не учитываются и т.д. И я не думаю, что это хорошая практика кодирования.

Какие еще варианты мы могли бы использовать?

Обновить:

Поскольку ответы вроде как упустили суть (они никоим образом не освобождают нас от размышлений о моделях и требуют дополнительного кода в классах моделей), я подумал, сработает ли этот вариант:

  1. Используйте пользовательский фильтр действий,
  2. переопределение OnActionExecuted()
  3. используйте отражение внутри этого метода, чтобы извлечь объект из модели, перечислить его общедоступные свойства и попытаться их инициализировать.

У меня частично реализованы шаги 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.