What is a Model ?
- Parts of the application that implement the domain logic
- also known as business logic
- Domain logic handles the data that is passed between the database and the UI
- For example, in an inventory system, the model keeps track of the items in storage and the logic to determine whether an item is in stock
- In addition, the model would be the part of the application that updates the database,when an item is sold and shipped out of the warehouse
- Often, the model also stores and retrieves model state in a database.
What is a ViewModel ?
- Allow you to shape multiple entities from one or more data models or sources into a single object
- Optimized for consumption and rendering by the view
It shows below image :
Why We Use ViewModel ?
1. If you need to pass more than one thing to a strongly-typed view (which is best practice),
you will generally want to create a separate class to do so.
2. This allows you to validate your ViewModel differently than your domain model for
attribute-based validation scenarios
3. Can be used to help shape and format data.
e.g: need a date or money value formatted a particular way?
ViewModel is the best place to do it.
4. The use of a ViewModel can make the interaction between model and view more simple
ViewModel Interaction with Model and View :
Where Should We Create ViewModel (physically) ?
1. In a folder called ViewModels that resides in the root of the project. (small applications)
2. As a .dll referenced from the MVC project (any size applications)
3. In a separate project(s) as a service layer, for large applications that generate
view/content specific data. (enterprise applications)
Best Practices When Using ViewModels
1. Put only data that youll render (use in View) in the ViewModel
2. The View should direct the properties of the ViewModel, this way it fits better for rendering
and maintenance
3. Use a Mapper when ViewModels become Complex ( How to Use ValueInjecter ? )
Lets Try with Simple Example
- C#,MVC 3 and Visual Studio 2010 has been used.
- Please follow an Inline Comments on Code.
- Simple application with product category drop down list, product name text box
and Save button
Our Domain Models Look Like Below
public class Product
{
public Product() { Id = Guid.NewGuid(); Created = DateTime.Now; }
public Guid Id { get; set; }
public string ProductName { get; set; }
public virtual ProductCategory ProductCategory { get; set; }
}
public class ProductCategory
{
public string CategoryName { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
Our ViewModel Looks Like Below
public class ProductViewModel
{
public Guid Id { get; set; }
[Required(ErrorMessage = "required")]
public string ProductName { get; set; }
public int SelectedValue { get; set; }
public virtual ProductCategory ProductCategory { get; set; }
[DisplayName("Product Category")]
public virtual ICollection<ProductCategory> ProductCategories { get; set; }
}
Our Controller Action Methods Look Like Below
[HttpGet]
public ActionResult AddProduct() //generate view with categories for enter product data
{
//for get product categories from database
var prodcutCategories = Repository.GetAllProductCategories();
//for initialize viewmodel
var productViewModel = new ProductViewModel();
//assign values for viewmodel
productViewModel.ProductCategories = prodcutCategories;
//send viewmodel into UI (View)
return View("AddProduct", productViewModel);
}
[HttpPost]
public ActionResult AddProduct(ProductViewModel productViewModel) //save entered data
{
//get product category for selected drop down list value
var prodcutCategory = Repository.GetProductCategory(productViewModel.SelectedValue);
//for get all product categories
var prodcutCategories = Repository.GetAllProductCategories();
//for fill the drop down list when validation fails
productViewModel.ProductCategories = prodcutCategories;
//for initialize Product domain model
var productObj = new Product
{
ProductName = productViewModel.ProductName,
ProductCategory = prodcutCategory,
};
if (ModelState.IsValid) //check for any validation errors
{
//save recived data into database
Repository.AddProduct(productObj);
return RedirectToAction("AddProduct");
}
else
{
//when validation failed return viewmodel back to UI (View)
return View(productViewModel);
}
}
Our View Looks Like Below
AddProduct.cshtml
@model YourProject.ViewModels.ProductViewModel //set your viewmodel here
<div class="boxedForm">
@using (Html.BeginAbsoluteRouteForm("add", new { action = "AddProduct"},FormMethod.Post }))
{
<ul>
<li style="width: 370px">
@Html.LabelFor(m => m.ProductCategories)
@Html.DropDownListFor(m => m.SelectedValue,new SelectList(Model.ProductCategories, "Id",
"CategoryName"),"-Please select a category -")
@Html.ValidationMessageFor(m => m.ProductCategory.Id)
</li>
<li style="width: 370px">
@Html.CompleteEditorFor(m => m.ProductName, labelOverride: "Product Name")
@Html.ValidationMessageFor(m => m.ProductName)
</li>
</ul>
<div class="action">
<button class="actionButton" type="submit">
<span>Save</span></button>
</div>
}
</div>
Repository Methods by using the Entity Framework
--- GetProductCategory() ---
//for get product category
public ProductCategory GetProductCategory(int categoryId)
{
return (from productCategory in Catalog.ProductCategories
where (productCategory.Id == categoryId)
select productCategory).FirstOrDefault();
}
---GetAllProductCategories()---
//for get all product categories
public List<ProductCategory> GetAllProductCategories()
{
return (from productCategory in Catalog.ProductCategories
select productCategory)
.OrderBy(p => p.CategoryName)
.ToList();
}
Conclusion
- ViewModels help you organize and manage data in MVC applications when you need to work with more complex data than the other objects allow.
- Using ViewModels gives you the flexibility to use data as you see fit.
- ViewModels are generally a more flexible way to access multiple data sources than domain models.
- Even for simple scenarios always try to use ViewModel approach to maintain consistency in Your coding practices.
I hope this helps to You.Comments and feedback greatly appreciated.
Happy Coding.
Related Article
How to Use ValueInjecter with Asp.net MVC ViewModel ?
Happy Coding.
Related Article
How to Use ValueInjecter with Asp.net MVC ViewModel ?
0 comments:
Post a Comment