Im still new to this MVC thing so is my understanding correct in terms of MVC View Models. They are essentially models that will interact directly with the view, where as a
You seem to have the right idea. Generally you will want to pass a view model to your view, especially in a case like this where you need data from two or more entity models. Far too often on this site we see people sending an entity model and then some other data by way of a ViewBag or ViewData, and inevitably, the solution to their problem is to use a view model.
The view model may look like this:
public class ViewModel
{
public int UserId { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
public DateTime CreatedDate { get; set; }
public String Description { get; set; }
}
This flattened version is useful for adding data annotations at the view model level instead of the entity model level. Handy when you may want to require a field in one view, but not in another.
Or like this
public class ViewModel
{
public UserModel UserModel { get; set; }
public String Description { get; set; }
}
You could do this
public class ViewModel
{
public UserModel UserModel { get; set; }
public ArticleModel ArticleModel { get; set; }
}
But then you would be sending superfluous data to the view which can often cause problems for folks as their app grows in scope
You could create a view model that contains all properties and collections needed for the view to show the data, in the correct format needed by the view. This view model is constructed by your controller by making use of the UserModel and ArticleModel instances. That might mean that in the view model you have properties that are not in the models and vice versa.
Now in your case it looks like your models have already been designed for your view, in that case, you could just use instances of them in your view model; to avoid unnecessary mappings.
Most important rule is that from within the view it should be easy to use properties of its viewmodel and display them, maybe applying some basic formatting (dates for example).
Based on the information you have given, I would just use the existing models in your viewmodel as properties, as you probably need all of them to be displayed and you avoid additional mapping.
Few rules & best practices to follow:--
Generally, it's a good practice to use a viewmodel. There are several advantages of using them. I think much of the details for viewmodel, you can find on the internet and on stack overflow as well.
And thus let me give an example or a starting point
let's say we have a viewmodel;
public class CategoryViewModel
{
[Key]
public int CategoryId { get; set; }
[Required(ErrorMessage="* required")]
[Display(Name="Name")]
public string CategoryName { get; set; }
[Display(Name = "Description")]
public string CategoryDescription { get; set; }
public ICollection<SubCategory> SubCategories { get; set; }
}
Now, if you wanna use this in your repository project. you can do something like this;
public List<CategoryViewModel> GetAllCategories()
{
using (var db =new Entities())
{
var categoriesList = db .Categories
.Select(c => new CategoryViewModel()
{
CategoryId = c.CategoryId,
CategoryName = c.Name,
CategoryDescription = c.Description
});
return categoriesList.ToList<CategoryViewModel>();
};
}
as, you can see. In case of viewmodel, you need to use the projections (as i have projected my entities to the viewmodel).
Now, in your controller, you can easily access them and pass it to the view itself;
ICategoryRepository _catRepo;
public CategoryController(ICategoryRepository catRepo)
{
//note that i have also used the dependancy injection. so i'm skiping that
_catRepo = catRepo;
}
public ActionResult Index()
{
//ViewBag.CategoriesList = _catRepo.GetAllCategories();
or
return View(_catRepo.GetAllCategories());
}
And now, your view should be of type CategoryViewModel
(the strongly typed)
@model IEnumerable<CategoryViewModel>
@foreach (var item in Model)
{
<h1>@item.CategoryName</h1>
}
I hope this gives you a starting point. Let me know, if you need more from me :D
Generally a class with a similar structure is being created. So, the view model is filled from the view and from the view model we manually update the model.
You may manually copy property by property from view model to model or copy using reflection or use APIs like auto mapper.