I can't understand, how to use TryUpdateModel and save the MVC architecture at the same time.
If I am not mistaken, work with datacontexts must be in the Model. So, such code
var db=new TestEverybody();//it is class, which was generated by EntityFramework var currentTesting=db.Testing.(t => t.id == id).First();
must be situated in the Model, not in the Controller, mustn't it?
But the ussual examples of TryUpdateModel usage is following:
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"); }
Doesn't this way break the MVC architecture? We work with database in the controller, not in the special Model class.
So, what is the best way to use TryUpdateModel in a real project?
TryUpdateModel<TModel>(TModel, String, String[], IValueProvider) Updates the specified model instance using values from the value provider, a prefix, and included properties.
The MVC convention is to put controllers in the Controllers folder that Visual Studio created when the project was set up. Let's take a look at a simple example of Controller by creating a new ASP.Net MVC project. Step 1 − Open the Visual Studio and click on File → New → Project menu option.
The Model-View-Controller (MVC) architectural pattern separates an application into three main components: the model, the view, and the controller. The ASP.NET MVC framework provides an alternative to the ASP.NET Web Forms pattern for creating MVC-based Web applications.
ASP.NET MVC 3 is a framework for building scalable, standards-based web applications using well-established design patterns and the power of ASP.NET and the . NET Framework. It installs side-by-side with ASP.NET MVC 2, so get started using it today!
Since the OP asked, here's an example of the ViewModel pattern, or as I like to call it - ASP.NET MVC done properly.
So why use a view specific model
We'll start with a simple entity:
public class Product { public int Id {get;set;} public string Name {get;set;} public string Description {get;set;} public decimal Price {get;set;} }
And let's say you have a simple form where the user can only update the Name
and Description
of the product. But you're using (the very greedy) TryUpdateModel.
So I use any number of tools (like Fiddler) to construct a POST myself and send the following:
Name=WhatverIWant&Description=UnluckyFool&Price=0
Well the ASP.NET MVC model binder is going to inspect the input form collection, see that these properties exist on your entity and automatically bind them for you. So when you call "TryUpdateModel" on the entity you've just retrieved from your database, all of the matching properties will be updated (including the Price!). Time for a new option.
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;} }
This contains just the properties we need in our view. Notice we've also added some validation attributes, display attributes and some mvc specific attributes.
By not being restricted in what we have in our view model it can make your views much cleaner. For example, we could render out our entire edit form by having the following in our view:
@Html.EditorFor(model => model)
Mvc will inspect all of those attributes we've added to our view model and automatically wire up validation, labels and the correct input fields (i.e. a textarea for description).
[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) }
It's fairly obvious from this code what it does. We don't have any undesirable effects when we update our entity since we are explicitly setting properties on our entity.
I hope this explains the View-Model pattern enough for you to want to use it.
So, such code must be situated in the Model, not in the Controller, mustn't it?
Not necessarily. Personally I prefer to put data access code in a repository. Then use constructor injection to pass some specific repository implementation to the controller (for example if I was using EF, I would write an EF repository implementation). So the controller will look like this:
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"); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With