How to make single view using viewmodel in asp.net mvc 4? - asp.net

I have different models Image,Page & PageCategories
public class Image
{
public int ImageId { get; set; }
public string ImageTitle { get; set; }
public string ImageURL { get; set; }
}
public class Page
{
public int PageId { get; set; }
public string PageTitle { get; set; }
public string Content { get; set; }
public int PageCategoryId { get; set; }
public virtual PageCategory PageCategory { get; set; }
}
public class PageCategory
{
public int PageCategoryId { get; set; }
public string CategoryName { get; set;
public virtual ICollection<Page> Pages { get; set; }
}
DBContext Class is
class DemoContext:DbContext
{
public DbSet<PageCategory> PageCategories { get; set; }
public DbSet<Page> Pages { get; set; }
public DbSet<Image> Images { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
I am wondering how to get all the model data to the home page using ViewModel.
For Ex.:
How to get image list and Page list in home page from multiple models?

You may want something like this :
viewModel :
//Create a viewModel with all the properties that you need
public class ViewModel
{
public int ImageId { get; set; }
public string ImageTitle { get; set; }
public string ImageURL { get; set; }
public int PageId { get; set; }
public string PageTitle { get; set; }
public string Content { get; set; }
public int PageCategoryId { get; set; }
public string CategoryName { get; set; }
}
Controller :
...
using (DemoContext db = new DemoContext()){
List<ImagePageViewModel> viewData = (from p in db.Page
join pc from db.PageCategory on p.PageCategoryId equals pc.PageCategoryId
select new ViewModel(){
PageTitle=p.PageTitle,
CategoryName = pc.CategoryName
//... set every property you want
})
}
return View(viewData );
note: I didn't add Image to the query because there is no explicit relation
between Image and the others table so i let you do it.

Create another class and define all above three into it. like below
public class MyView
{
public List<Image> Images { get; set; }
public List<Page> Pages { get; set; }
public List<PageCategory> PageCategories { get; set; }
}
Controller Action:-
public ActionResult Index()
{
MyView myView = // Get it using your logic
return View(myView);
}

finally got my answer:
public class ViewModelDemo
{
public IEnumerable<Image> images { get; set; }
public IEnumerable<Pages> pages { get; set; }
public IEnumerable<PageCategory> pagecategories { get; set; }
}
Then in HomeController
private DemoContext db=new DemoContext();
public ActionResult Index()
{
ViewModelDemo vm = new ViewModelDemo();
vm.images = db.Images.ToList();
vm.pages=db.Pagess.ToList();
vm.pagecategories=db.PageCategories.ToList();
return View(vm);
}

Related

generate a list of products of a category

I am developing a shop application and I need to show products of each category. The problem is each product is created from a product template which is stored in a table and each template is related to a category. here is the product model:
namespace fardashahr.Models
{
[Table("Product")]
public class ProductModel
{
public ProductModel()
{
if (Specs == null)
{
Specs = new Dictionary<string, SpecItemsModel>();
}
}
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public int ProductTemplateId { get; set; }
[Required]
public bool IsPublished { get; set; }
[Required]
public bool InStock { get; set; }
[Range(95, 110)]
public float SyncRate { get; set; }
public DateTime? ProductionDate { get; set; }
[Required]
public DateTime RegisterationDate { get; set; }
public string ImageName { get; set; }
public IEnumerable<string> GalleryImages { get; set; }
[NotMapped]
public Dictionary<string, SpecItemsModel> Specs { get; set; }
[ForeignKey("ProductTemplateId")]
public virtual ProductTemplateModel ProductTemplate { get; set; }
[ForeignKey("ManufacturerId")]
public virtual CodingItemModel Manufacturer { get; set; }
[ForeignKey("BrandId")]
public virtual CodingItemModel Brand { get; set; }
[ForeignKey("ModelId")]
public virtual CodingItemModel Model { get; set; }
[ForeignKey("SeriesId")]
public virtual CodingItemModel Series { get; set; }
}
}
and here is the the ProductTemplate:
namespace fardashahr.Models
{
[Table("ProductTemplate")]
public class ProductTemplateModel
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[StringLength(500)]
public string Name { get; set; }
[Required]
public int CategoryId { get; set; }
[StringLength(500)]
public string Description { get; set; }
[ForeignKey("CategoryId")]
public virtual CategoryModel Category{ get; set; }
}
}
and the controller is:
namespace fardashahr.Controllers
{
public class ProductsController : Controller
{
// GET: Products
public ActionResult Index()
{
return RedirectToAction("Index", "Home");
}
public ActionResult Category(string name)
{
//declare a list of products
List<ProductModel> productList;
using(MainModel db = new MainModel())
{
//get category id
CategoryModel category = db.Categories.Where(x => x.CategorytUrl == name).FirstOrDefault();
int catId = category.Id;
//initialize the list
productList = db.Products.Where(x => x. == catId).ToList();
}
}
}
}
finaly, what I want to know is how to initialize a list of products.
In your models, you added virtual keyword which indicates that navigation property will be automatically loaded without the need of LINQ lambda .include() expression.
Hence you can immediately access the navigation property and load the list like this;
productList = db.Products.Where(x => x.ProductTemplate.CategoryId == catId).ToList();
string categoryNameOfFirstProduct = productList.FirstOrDefault().ProductTemplate.Category.Name;
string categoryNameOfFirstProduct = productList.FirstOrDefault().ProductTemplate.Category.CategorytUrl;

How to call Db view file in repository pattern?

I am creating a view file in SQL Server as shown in the image below.
and I created a model to get results from this view:
public class FactALLCousumption : BaseEntity, IAggregateRoot
{
public double sumActiveImportTotal { get; set; }
public DateTime hour { get; set; }
public int fullDateAlternateKey { get; set; }
}
But I can't call this view in my repository. My repository code is bellow:
public class FactCousumptionRepository: GenericRepository<FactCousumption>, IFactCousumptionRepository
{
public DbContext _dbContext;
public FactCousumptionRepository(BaseDbContext context) : base(context)
{
_dbContext = context;
}
public async Task<FactALLCousumption> GetTotalAllCousumption()
{
}
}
In EF Core 2.2 or 2.1, you could use Query types.
According to the screenshot and the model to be used for the View you provided , I make a simple working demo like below , you could refer to and make the modification as per your demand:
1.Model
public class FactCousumption
{
public int Id { get; set; }
public double SumActiveImportTotal { get; set; }
public int DateKeyId { get; set; }
[ForeignKey("DateKeyId")]
public Dim_Date Dim_Date { get; set; }
public int TimeAltKeyId { get; set; }
[ForeignKey("TimeAltKeyId")]
public Dim_Time Dim_Time { get; set; }
public int TariffKeyId { get; set; }
[ForeignKey("TariffKeyId")]
public Dim_Tariff Dim_Tariff { get; set; }
}
public class Dim_Date
{
[Key]
public int DateKey { get; set; }
public int FullDateAlternateKey { get; set; }
public DateTime Date { get; set; }
public ICollection<FactCousumption> FactCousumptions { get; set; }
}
public class Dim_Time
{
[Key]
public int TimeAltKey { get; set; }
public DateTime Hour { get; set; }
public ICollection<FactCousumption> FactCousumptions { get; set; }
}
public class Dim_Tariff
{
[Key]
public int TariffType { get; set; }
public string TariffName { get; set; }
public ICollection<FactCousumption> FactCousumptions { get; set; }
}
2.Create SQL View
CREATE VIEW [dbo].[View1]
AS SELECT SUM(FactCousumption.SumActiveImportTotal) AS consumption ,Dim_Time.HOUR,Dim_Date.FullDateAlternateKey,Dim_Tariff.TariffName
FROM FactCousumption INNER JOIN
Dim_Date ON FactCousumption.DateKeyId = Dim_Date.DateKey INNER JOIN
Dim_Time ON FactCousumption.TimeAltKeyId=Dim_Time.TimeAltKey INNER JOIN
Dim_Tariff ON FactCousumption.TariffKeyId=Dim_Tariff.TariffType
GROUP BY Dim_Date.FullDateAlternateKey, Dim_Time.HOUR ,Dim_Tariff.TariffName
3.The model that is used for the view , note : the property name in model should be consistent with those in the view
public class FactALLCousumption
{
public double consumption { get; set; }
public DateTime hour { get; set; }
public int fullDateAlternateKey { get; set; }
}
4.DbContext , create a DbQuery property in my DbContext to consume the view results inside the Model and set up the View especially if you have different view name than your Class.
public DbQuery<FactALLCousumption> FactALLCousumption { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Query<FactALLCousumption>().ToView("View1");
}
5.Finally you can easily get the results of the View like this.
public async Task<FactALLCousumption> GetTotalAllCousumption()
{
var result = await _context.FactALLCousumption.FirstOrDefaultAsync();
return result;
}
Note: It's worth noting that DbQuery won't be/is not supported anymore in EF Core 3.0. See here

MVC 5 Complex View Model binding is not working

public class CreateProjeModel
{
public Proje Proje { get; set; }
public List<GeometryModel> GeometryList { get; set; }
public CreateProjeModel()
{
Proje = new Proje();
GeometryList = new List<GeometryModel>();
}
}
public class GeometryModel
{
public List<PointModel> PointList { get; set; }
public GeometryModel()
{
PointList = new List<PointModel>();
}
}
public class PointModel
{
public int X { get; set; }
public int Y { get; set; }
}
public class Proje : EntityBase
{
public int FirmaId { get; set; }
public int IlId { get; set; }
public int? IlceId { get; set; }
public int PlanTurId { get; set; }
public int EtudTurId { get; set; }
public int EtudAmacId { get; set; }
public int DilimId { get; set; }
public string Aciklama { get; set; }
public virtual Firma Firma { get; set; }
public virtual IL Il { get; set; }
public virtual ILCE Ilce { get; set; }
public virtual PlanTur PlanTur { get; set; }
public virtual EtudTur EtudTur { get; set; }
public virtual EtudAmac EtudAmac { get; set; }
public virtual Dilim Dilim { get; set; }
}
I have a complex model named CreateProjeModel. I'm using 'for' to loop collection properties and binding like below:
#Html.TextBoxFor(m => m.GeometryList[i].PointList[j].X)
Action is like below:
[HttpPost]
public async Task<ActionResult> Create(CreateProjeModel proje)
{
//ToDo
return View(proje);
}
Posted data is below:
When it comes to action, GeometryList is empty and Proje's properties are not set to post values. Where am I doing wrong?
Your problem is that your CreateProjeModel model has a property named Proje, but the parameter of your Create() method is also named proje. Your need to change the method signature to (say)
public async Task<ActionResult> Create(CreateProjeModel model)
where the parameter name is not the same as the nae of one of your properties

Automapper configuration for object

I have these classes
public class NamedEntityViewModel
{
public string Name { get; set; }
}
public class NamedEntityListViewModel
{
public List<NamedEntityViewModel> List { get; set; }
}
public class Album : INamedEntity
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public virtual ICollection<Song> Songs { get; set; }
[Required]
public int AlbumNumber { get; set; }
}
I have a List<Album> and I want to map that to NamedEntityListViewModel with NamedEntityViewModel.Name mapping to Album.Name. How do I set this up in Automapper?
Try something like that:
First create you mapper:
Mapper.CreateMap<Album, NamedEntityViewModel>();
For the mapping do this:
// yourAlbumList is a List<Album>
var albumListVm = new NamedEntityListViewModel();
albumListVm.List = Mapper.Map<IEnumerable<NamedEntityViewModel>>(yourAlbumList);
This should do the job

Save Relation between User and Entity in ASP.NET MVC4

I have an Exercise entity defined in my ASP.NET MVC4 Web Application.
I'm using the Form Authentication with the default AccountModels.cs class.
I have class which looks like
public class Exercise
{
private DateTime _DateCreated = DateTime.Now;
private UserProfile _Teacher;
public int Id{ get; set; }
public string Question { get; set; }
public int Anwser { get; set; }
public string Category { get; set; }
public int maxNbrOfAttempts { get; set; }
public string Hints { get; set; }
public virtual ICollection<Quiz> Quizzes { get; set; }
public DateTime Date
{
get { return _DateCreated; }
set { _DateCreated = value; }
}
public UserProfile Author
{
get { return _Teacher; }
set { _Teacher = value; }
}
}
Am I using the UserProfile correctly to link between an Exercise and a logged in user?
How can I get the current UserProfile in my controller?
Change it like this:
public class Exercise
{
public Exercise()
{
this.Date = DateTime.Now;
this.Author = User.Identity.Name; //Write this line if you want to set
//the currently logged in user as the Author
public int Id{ get; set; }
public string Question { get; set; }
public int Anwser { get; set; }
public string Category { get; set; }
public int maxNbrOfAttempts { get; set; }
public string Hints { get; set; }
public virtual ICollection<Quiz> Quizzes { get; set; }
public virtual DateTime Date { get; set; }
public virtual UserProfile Author { get; set; }
}

Resources