Asp mvc lists product information using View Model

I am trying to list individual product details in a view. The product specification changes dynamically, because the specifications are added according to the table in the table, which means that we can add a huge number of specifications for each product (as is done on e-commerce sites). Right now I can fulfill the requirement with the ViewBag , but I decided to use ViewModel as the best practice.

Model Class:

 // Product: public partial class ProductTable { public ProductTable() { this.SpecificationsTable = new HashSet<SpecificationsTable>(); } public int ProductID { get; set; } public string Title { get; set; } public string SmallDescription { get; set; } public string FullDescription { get; set; } public virtual ICollection<SpecificationsTable> SpecificationsTable { get; set; } } //Specifications: public partial class SpecificationsTable { public int SpecificationsID { get; set; } public string SpecificationName { get; set; } public string SpecificationValue { get; set; } public Nullable<int> ProductID { get; set; } public virtual ProductTable ProductTable { get; set; } } 

ViewModel:

 public class DetailsViewModel { public int ProductID { get; set; } public string Title { get; set; } public string SmallDescription { get; set; } public string FullDescription { get; set; } public string SpecificationName { get; set; } public string SpecificationValue { get; set; } } 

Actionmethod

 public ActionResult ProductDetails(int id) { var details = (from c in dbo.ProductTable join s in dbo.SpecificationsTable on c.ProductID equals s.ProductID where c.ProductID == id select new DetailViewModel { Title = c.Title, SmallDescription = c.SmallDescription, FullDescription = c.FullDescription }).ToList(); // To remove repeated product title , small and full description var distinctItems = details.GroupBy(x => x.ProductID).Select(y => y.First()); // To show product title, small and full description for this product ViewBag.ProductDetails = distinctItems; var specifications = (from c in dbo.ProductTable join s in dbo.SpecificationsTable on c.ProductID equals s.ProductID where c.ProductID == id select new DetailViewModel { SpecificationName = s.SpecificationName, SpecificationValue = s.SpecificationValue }).ToList(); // To show list of specifications for this product ViewBag.Specifcations = specifications; return View(); } 

Expected Result:

Details:

 Title: New Samsung offer SmallDescription : Something small FullDescription : Something full 

Specifcations:

 Mobile Name :Samsung Model : 2015 Price : 70 $ Color: White 

I am using the first database method and I am trying to find out how we can use the view model here.

+4
source share
2 answers

The current view model does not reflect what you want to display in the view, which is a multiple specification for each product, so you need a collection property. Change view models to

 public class SpecificationVM { public string Name { get; set; } public string Value { get; set; } } public class ProductVM { public string Title { get; set; } public string SmallDescription { get; set; } public string FullDescription { get; set; } IEnumerable<SpecificationVM> Specifications { get; set; } } 

Then in the controller fill the model with

 public ActionResult ProductDetails(int id) { var product = db.ProductTable.Where(p => p.ProductID == id).FirstOrDefault(); // note you may need to add .Include("SpecificationsTable") in the above if (product == null) { return new HttpNotFoundResult(); } ProductVM model = new ProductVM() { Title = product.Title, SmallDescription = product.SmallDescription, FullDescription = product.FullDescription, Specifications = product.SpecificationsTable.Select(s => new SpecificationVM() { Name = s.SpecificationName, Value = s.SpecificationValue }) }; return View(model); } 

Then in view

 @model yourAssembly.ProductVM <h2>Details</h2> @Html.DisplayNameFor(m => m.Title) @Html.DisplayFor(m => m.Title) .... // ditto for SmallDescription and FullDescription <h2>Specifications</h2> @foreach(var item in Model.Specifications) { @Html.DisplayFor(m => item.Name) @Html.DisplayFor(m => item.Value) } 
+3
source

View modes are really a way to go here. I will not dwell on what viewing models, as you have already stated in your code, so I assume that you already know their purpose and functionality. However, for completeness - viewmodels represent only the data that you want to display in your view; assuming the view displays the first and last name of the employee, there is no reason to send the Employee object back when you really only need two of its properties.

According to the definition of a short viewmodel above, to return the viewmodel instead of attaching the returned object to the ViewBag , you simply create a class that will only store the data that you want to present in the view. So, based on your โ€œexpected resultโ€, your view model will look something like this:

 public class YourViewModel { public string Title { get; set; } public string SmallDescription { get; set; } public string FullDescription { get; set; } public string MobileName { get; set; } public int ModelYear { get; set; } public decimal Price { get; set; } public string Color { get; set; } } 

Once you create an instance and run your viewmodel, navigate to it:

 var yourViewModel = new YourViewModel(); //populate it and pass it to the view return View(yourViewModel); 

At the top of your view, declare an @model variable which is of type YourViewModel :

 @model YourViewModel 

.. and you are good to go. Therefore, if you want to print the name of the mobile device in the view:

 @Model.MobileName 

Keep in mind that although you can only have one @model for each view, you can still have multiple view modes. This is possible by creating a parent view model to preserve all view-related view modes and set this instead of @model :

 public class ParentViewModel { //all the viewmodels which are relevant to your view public DetailsViewModel DetailsViewModel { get; set; } public YourViewModel YourViewModel { get; set; } //...etc } 

Once you create an instance and run your viewmodel, navigate to it:

 var parentViewModel = new ParentViewModel(); var yourViewModel = new YourViewModel(); //populate it and attach it to the parent viewmodel parentViewModel.YourViewModel = yourViewModel; return View(parentViewModel); 

This time, at the top of your view, declare the @model type instead of the @model variable:

 @model ParentViewModel 

.. and you are good to go. Using the same example, if you want to print the name of the mobile device in the view:

 @Model.YourViewModel.MobileName 

Keep in mind that I did not pay much attention to how you structured your view models, but rather explained how to pass one (or more) viewmodels back to your view and use them instead of the ViewBag (according to your question). In order for your presentations to be truly filled and looking, Stephen Muke's answer is the way to go.

+4
source

All Articles