Реальный пример TryUpdateModel, ASP.NET MVC 3

Я не могу понять, как использовать TryUpdateModel и одновременно сохранять архитектуру MVC.

Если я не ошибаюсь, работа с datacontexts должна быть в Модели. Итак, такой код

var db=new TestEverybody();//it is class, which was generated by EntityFramework var currentTesting=db.Testing.(t => t.id == id).First(); 

должен находиться в Модели, а не в Контроллере, не так ли?

Но вот пример использования TryUpdateModel:

  public ActionResult Edit(Testing obj)//Testing collection { var db = new TestEverybody(); var currentTesting=db.Testing.(t => t.id == obj.id).First(); TryUpdateModel(currentTesting); db.SaveChanges(); return RedirectToAction("Index"); } 

Разве это не нарушает архитектуру MVC? Мы работаем с базой данных в controllerе, а не в специальном classе модели.

Итак, каков наилучший способ использования TryUpdateModel в реальном проекте?

    2 Solutions collect form web for “Реальный пример TryUpdateModel, ASP.NET MVC 3”

    Поскольку OP спросил, вот пример шаблона ViewModel или, как мне нравится его называть – ASP.NET MVC выполнен правильно.

    Итак, зачем использовать конкретную модель просмотра?

    1. Вы должны передавать информацию только на свое мнение, которое вам нужно.
    2. Часто вам нужно добавить дополнительные мета-данные вида (например, атрибуты заголовка / описания). Они не принадлежат вашим сущностям.
    3. Использование TryUpdateModel / UpdateModel неверно. Не используйте (я объясню, почему).
    4. Очень редко ваши модели просмотра будут точно соответствовать вашим объектам. Люди часто заканчивают тем, что добавили дополнительный рывок к своим сущностям или (не намного лучше), просто используя ViewBag, а не сильно типизированные свойства модели представления.
    5. Если вы используете ORM, вы можете столкнуться с проблемами с Lazy загруженными свойствами (N + 1). Ваши мнения не должны вызывать запросы.

    Мы начнем с простого объекта:

     public class Product { public int Id {get;set;} public string Name {get;set;} public string Description {get;set;} public decimal Price {get;set;} } 

    И, допустим, у вас простая форма, в которой пользователь может обновлять Name и Description продукта. Но вы используете (очень жадный) TryUpdateModel.

    Поэтому я использую любое количество инструментов (например, Fiddler) для создания POST и отправляю следующее:

    Имя = WhatverIWant & Description = UnluckyFool & Price = 0

    Хорошо, что связующее устройство ASP.NET MVC будет проверять коллекцию входных форм, видно, что эти свойства существуют на вашей сущности и автоматически связывают их для вас. Поэтому, когда вы вызываете «TryUpdateModel» на сущности, которую вы только что извлекли из своей базы данных, все соответствующие свойства будут обновлены (включая цену!). Время для новой опции.

    Просмотреть конкретную модель

     public class EditProductViewModel { [HiddenInput] public Guid Id {get;set;} [Required] [DisplayName("Product Name")] public string Name {get;set;} [AllowHtml] [DataType(DataType.MultilineText)] public string Description {get;set;} } 

    Это содержит только те свойства, которые нам нужны в нашем представлении. Обратите внимание, что мы также добавили некоторые атрибуты проверки, отображаемые атрибуты и некоторые специфические атрибуты mvc.

    Не ограничиваясь тем, что у нас есть в нашей модели, это может сделать ваши взгляды более чистыми. Например, мы могли бы отобразить всю форму редактирования, имея на наш взгляд следующее:

     @Html.EditorFor(model => model) 

    Mvc проверит все те атрибуты, которые мы добавили в нашу модель представления, и автоматически подключаем проверки, метки и правильные поля ввода (т. Е. Текстовое поле для описания).

    ОТКРЫТИЕ формы

     [HttpPost] public ActionResult EditProduct(EditProductViewModel model) { var product = repository.GetById(model.Id); if (product == null) { return HttpNotFound(); } // input validation if (ModelState.IsValid) { // map the properties we **actually** want to update product.Name = model.Name; product.Description = model.Description; repository.Save(product); return RedirectToAction("index"); } return View(model) } 

    Из этого кода довольно очевидно, что он делает. У нас нет каких-либо нежелательных эффектов, когда мы обновляем наш объект, поскольку мы явно устанавливаем свойства для нашего объекта.

    Надеюсь, это объяснит модель View-Model, достаточную для того, чтобы вы захотели ее использовать.

    Итак, такой код должен находиться в Модели, а не в Контроллере, не так ли?

    Не обязательно. Лично я предпочитаю помещать код доступа к данным в repository. Затем используйте инъекцию конструктора, чтобы передать определенную реализацию репозитория controllerу (например, если я использовал EF, я бы написал реализацию репозитория EF). Таким образом, controller будет выглядеть так:

     public class HomeController: Controller { private readonly IMyRepository _repository; public HomeController(IMyRepository repository) { _repository = repository; } public ActionResult Edit(int id) { var currentTesting = _repository.GetTesting(id); TryUpdateModel(currentTesting); _repository.SaveChanges(); return RedirectToAction("Index"); } } 
    Давайте будем гением компьютера.