How you can display a sample based on the data model. but with fields not described in it? For example, there is a controller:

public ActionResult Index() { var asd = db.tbl .GroupBy(x => DbFunctions.TruncateTime(x.q_Date)) .Select (x => new { Val = x.Count(), Dat = (DateTime)x.Key }).ToList(); ViewBag.Asd = asd; return View(); } 

here is a tbl table with a q_Date field.

But this sample cannot be displayed in view:

 @foreach (var c in ViewBag.Asd) { <tr> <td> @c.Dat </td> <td> @c.Val </td> </tr> } 

Error - "object" does not contain definitions for "Dat": @ c.Dat Do you have to create a separate class in Models for each such case? can not it somehow get around?

  • do not use ViewBag - Yaroslav
  • And how then to display List <> in view? If it is not described in Models? - JorJ
  • 2
    The correct approach is to create a separate class model. Or you can use dynamic. - Alexander Petrov
  • And if there are a lot of such List <> that need to be output? For each create a separate class? Or can one describe all the required fields within one controller? - JorJ
  • 2
    Yes, create a separate class. Using a Model to Pass . - Alexander Petrov

1 answer 1

Such classes can be called Dto, ViewModel - and put them in separate from the folder with the models (if you have a single application). Do something like this:

Create a view model:

 public class BookListViewModel { public int Val { get; set; } public DateTime Dat { get; set; } } 

Make an action controller type:

 public ActionResult Index() { var model = db.tbl .GroupBy(x => DbFunctions.TruncateTime(x.q_Date)) .Select (x => new { V = x.Count(), D = (DateTime)x.Key }) .AsNoTracking() .AsEnumerable() .Select (x => new BookListViewModel { Val = xV, Dat = (DateTime)xD }) .ToArray(); return View(model); } 

(Here you need to understand the difference between IEnumerable and IQueryable, for example, see here )

You can also make a constructor in the class:

 public class BookListViewModel { public BookListViewModel (int val, DateTime dat) { this.Val = val; this.Dat = dat; } public int Val { get; private set; } public DateTime Dat { get; private set; } } 

And cut the record to:

 public ActionResult Index() { var model = db.tbl .GroupBy(x => DbFunctions.TruncateTime(x.q_Date)) .Select (x => new { V = x.Count(), D = (DateTime)x.Key }) .AsNoTracking() .AsEnumerable() .Select (x => new BookListViewModel(x)) .ToArray(); return View(model); } 

Or even go to the use avtomapera.

In the view, iterate the model:

 @model IEnumerable<BookListViewModel> @foreach (var item in Model) { <tr> <td> @item.Dat </td> <td> @item.Val </td> </tr> } 
  • (There is no finished project at hand, so if there are mistakes, let me know how I will get to the studio, correct it) - AK