Display ICollection values in one column - asp.net-mvc

I can't display values in grid from ICollection. I use this lib http://mvc6-grid.azurewebsites.net/.
I tried to create a cycle to iterate through ICollection but it didn't work
//Model
public partial class CsoSupport {
public CsoSupport()
{
CsoSupportMonitoring = new HashSet<CsoSupportMonitoring>();
}
public string ExpectedResult { get; set; }
public ICollection<CsoSupportMonitoring> CsoSupportMonitoring { get; set; }
}
//View
#(Html.Grid(Model.csoFinancialSupportModel).Build(columns =>
{
columns.Add(model => model.ExpectedResult).Titled("ExpectedResult"); //works
columns.Add(model => model.CsoSupportMonitoring).Titled("Date"); //not working
}
I want to display dates from model.csoSupportMonitoring

Maybe create a property specifically for display? And do something like the following.
//Class
public partial class CsoSupport {
public CsoSupport()
{
CsoSupportMonitoring = new HashSet<CsoSupportMonitoring>();
}
public string ExpectedResult { get; set; }
public string CsoSupportMonitoringDates {
get {
return string.Join(",", CsoSupportMonitoring.Dates):
}
}
public ICollection<CsoSupportMonitoring> CsoSupportMonitoring { get; set; }
}
//View
#(Html.Grid(Model.csoFinancialSupportModel).Build(columns =>
{
columns.Add(model => model.ExpectedResult).Titled("ExpectedResult");
columns.Add(model => model.CsoSupportMonitoringDates).Titled("Date");
}

Related

How to pass two vars from one controller into one view

I want this two methods pass to one view :
public IEnumerable<ProfitAndCostViewModel> getProfitSum()
{
var profBalance = db.Profits
.Where(x => x.IdUser.UserId == WebSecurity.CurrentUserId)
.GroupBy(x => x.IdUser.UserId)
.Select(x => new ProfitAndCostViewModel { ProfitSum = x.Sum(y => y.Value) })
.ToList();
return profBalance;
}
public IEnumerable<ProfitAndCostViewModel> getCostSum()
{
var costBalance = db.Costs
.Where(x => x.IdUser.UserId == WebSecurity.CurrentUserId)
.GroupBy(x => x.IdUser.UserId)
.Select(x => new ProfitAndCostViewModel { CostSum = x.Sum(y => y.Value) })
.ToList();
return costBalance;
}
in my ActionResult I Have this:
ProfitAndCostViewModel pcv = new ProfitAndCostViewModel();
pcv.ProfModel =getProfitSum();
pcv.CostModel =getCostSum();
return View(pcv);
And in ProfitAndCostViewModel code is this:
public double ProfitSum { get; set; }
public double CostSum { get; set; }
public double FinalBalance { get; set; }
public IEnumerable<ProfitAndCostViewModel> ProfModel { get; set; }
public IEnumerable<ProfitAndCostViewModel> CostModel { get; set; }
this is the error:
The model item passed into the dictionary is of type 'WHFM.ViewModels.ProfitAndCostViewModel', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[WHFM.ViewModels.ProfitAndCostViewModel]'.
Create a view model which has them both;
public class BigViewModel
{
public List<ProfitsModel> ProfModel { get; set; }
public List<CostsModel> CostModel { get; set; }
}
And controller
public ActionResult Index()
{
BigViewModel model = new BigViewModel();
model.costBalance = db.Costs...;
model.profBalance = db.Profits...;
return View(model)
}
You can wrap your parameters into a ViewModel or use a ViewBag

DropDownListFor not working with nested list

My DropDownListFor not bind selected item.
This is correct model:
public class DeliveryOrderModel
{
public BoxInfo Boxes { get; set; }
public class BoxInfo
{
public long? CountryID { get; set; }
public IEnumerable<SelectListItem> Countries { get; set; }
}
}
And in this model problem:
public class DeliveryOrderModel
{
public List<BoxInfo> Boxes { get; set; }
public class BoxInfo
{
public long? CountryID { get; set; }
public IEnumerable<SelectListItem> Countries { get; set; }
}
}
This is SelectItems
var Countries = new SelectList(new[]
{
new { CountryID = 1, Text = "Name1" },
new { CountryID = 2, Text = "Name2" },
new { CountryID = 3, Text = "Name3" }
} ,"CountryID","Text");
This dropdown work with first model:
Html.DropDownListFor(model => model.Boxes.CountryID, Model.Boxes.Countries)
And this is trouble dropdown:
Html.DropDownListFor(model => model.Boxes[0].CountryID, Model.Boxes[0].Countries)
First thought - SelectList is a collection, not an array, so you may need something like:
Html.DropDownListFor(model => model.Boxes.First().CountryID,
Model.Boxes.First().Countries)
May also need a lamda expresson for the .First
ADDITION
Model might be like
public class DeliveryOrderModel
{
public List<BoxInfo> Boxes { get; set; }
public class BoxInfo
{
publix Box myBox { get; set; }
public long? CountryID { get; set; }
}
}
CountryList becomes a separate and independent SelectList ViewModel.
And finally the view
Html.DropDownListFor(model => model.Boxes[0].CountryID, Countries)
Or a ForEach to iterate through the boxes, or ...
OK?

How to display selected text, not selected value, of a dropdownlist in a displaytemplate?

So I have this piece of code in my displaytemplate:
#Html.DropDownListFor(blah => blah.InputtedData, ddv)
and I get an actual dropdownlist. I've tried this piece of code:
#Html.DisplayFor(blah => blah.InputtedData, ddv)
And I get 1 (the number one), the selectedvalue. But I want to display Yes, the selectedtext. So how do I display the selectedtext in a dropdownlist in a displaytemplate and not the selectedvalue?
Per request:
namespace TESTMVC.ViewModels
{
public class CtrlInputDataModel
{
public CtrlTypeModel RowCtrl { get; set; }
public long InputtedDataID { get; set; }
public string InputtedData { get; set; }
public DateTime InputtedDate { get; set; }
public CtrlInputDataModel()
{
}
public CtrlInputDataModel (CtrlTypeModel newRowCtrl, long newInputtedDataID, string newInputtedData, DateTime newInputtedDate)
{
RowCtrl = newRowCtrl;
InputtedDataID = newInputtedDataID;
InputtedData = newInputtedData;
InputtedDate = newInputtedDate;
}
}
}
The ViewModel that ddv is based on:
namespace TESTMVC.ViewModels
{
public class DefaultValueModel
{
public string Label { get; set; }
public string Value { get; set; }
public DefaultValueModel()
{
}
public DefaultValueModel(string newLabel, string newValue)
{
Label = newLabel;
Value = newValue;
}
}
}
You cannot do it with the built in Html.DisplayFor. However you can create a custom displaytemplate e.g. /Views/Shared/DisplayTemplates/DropdownListTest.cshtml where you manually select the text from the dropdownlist values based on your property:
#model string
#((IEnumerable<SelectListItem>)ViewData["ddv"])
.Where(s => Model == s.Value)
.Select(s => s.Text).SingleOrDefault()
Then you can use it with the following (little bit complex) syntax:
#Html.DisplayFor(blah => blah.InputtedData,
"DropdownListTest", //template name
new { ddv = ddv } // aditional view data: the property name needs to be ddv
})
But if don't plan to reuse this functionality just inline your the logic and use this instead of the Html.DisplayFor:
#ddv.Where(s => s.Value == Model.InputtedData)
.Select(s => s.Text).SingleOrDefault()

Object reference not set to an instance of an object on DropDownListFor

This is driving me crazy! I am trying to create a drop down list that gets it's values from the database. I am new to MVC, so it's probably something simple, but I can't figure it out. Please help!
View Model:
public class LoadInputModel
{
public GeoRegion GeoRegion { get; set; }
public System.Guid Id { get; set; }
public IEnumerable<GeoRegion> Description { get; set; }
}
Here is my controller:
[HttpPost]
public ActionResult LoadShape(LoadInputModel LoadInputModel)
{
LoadInputModel.Description = db.GeoRegions.Select(a => a);
return View(LoadInputModel);
}
Here is my htmlhelper:
#Html.DropDownListFor(m => m.Description,Model.Description.Select(c => new SelectListItem { Text = c.Description, Value = c.Id.ToString() }), "-----Select Category----")
I guess your Description property value is null, So you may need to initialize it before assigning some values to that
if( LoadInputModel.Description==null)
{
LoadInputModel.Description=new List<GeoRegion>();
}
LoadInputModel.Description = db.GeoRegions.Select(a => a);
Or you can do it in the class level itself so taht you dont need to do in many places
public class LoadInputModel
{
public GeoRegion GeoRegion { get; set; }
public System.Guid Id { get; set; }
public IEnumerable<GeoRegion> Description { get; set; }
public LoadInputModel()
{
if(Description==null)
{
Description=new List<GeoRegion>();
}
}
}

Domain Modeling Question using C# with Entity Framework CTP 4

I am trying to model out a album that has a collection of photos. Each Album will have a collection of Photos and a Photo that is a thumb. This is what I have but EF does not seem to like it:
public class Album : IEntity {
private DateTime _dateCreated;
public Album() {
_dateCreated = SystemTime.Now();
Photos = new List<Photo>();
}
public long Id { get; set; }
public string Name { get; set; }
public string Location { get; set; }
public DateTime DateCreated
{
get { return _dateCreated; }
set { _dateCreated = value; }
}
public virtual Site Site { get; set; }
public virtual Photo Thumbnail { get; set; }
public virtual ICollection<Photo> Photos { get; set; }
}
public class Photo : IEntity {
public Photo() {
_dateCreated = SystemTime.Now();
}
private DateTime _dateCreated;
public long Id { get; set; }
public string Caption { get; set; }
public string FileName { get; set; }
public DateTime DateCreated
{
get { return _dateCreated; }
set { _dateCreated = value; }
}
public virtual Album Album { get; set; }
}
public class AlbumMap : EntityConfiguration<Album>
{
public AlbumMap()
{
HasKey(x => x.Id);
Property(x => x.Id).IsIdentity();
Property(x => x.Location).IsVariableLength().HasMaxLength(80);
Property(x => x.Name).IsVariableLength().HasMaxLength(80).IsRequired();
Property(x => x.DateCreated);
MapSingleType(a => new
{
a.Id,
SiteId = a.Site.Id,
ThumbnailId = a.Thumbnail.Id,
a.Location,
a.Name,
a.DateCreated
}).ToTable("Albums");
}
}
public class PhotoMap : EntityConfiguration<Photo>
{
public PhotoMap()
{
HasKey(x => x.Id);
Property(x => x.Id).IsIdentity();
Property(x => x.FileName).IsVariableLength().HasMaxLength(255).IsRequired();
Property(x => x.Caption).IsVariableLength().HasMaxLength(255);
Property(x => x.DateCreated);
MapSingleType(a => new
{
a.Id,
SiteAlbumId = a.Album.Id,
a.FileName,
a.Caption,
a.DateCreated
}).ToTable("AlbumPhotos");
}
}
Am I missing something or does this look right? I am expecting EF to generate a 1 to many in my database but it keeps creating a reference table between Album and Photos (Album_Photos) but this should not be a many-to-many. Any help would be great.
By convention, EF code first does not create a link table in typical one to many scenario, the reason that you are getting it is because your associations between Album and Photo objects has been taken by EF as being a kind of many to many association:
Each album has a collection of Photos and also each Photo has a collection of Albums that this photo is a thumbnail for (although the related navigation property is not explicitly specified on Photo class and only Album has a Thumbnail property).
Solution:
As of EF CTP4, the only way to fix this is by leveraging Fluent API, but before that, I modify your model a little bit and add two explicit FKs to your model to give you ultimate flexibility to work with your objects. They are AlbumId on Photo and ThumbnailId on Album:
public class Photo {
public long Id { get; set; }
public string Caption { get; set; }
public string FileName { get; set; }
public DateTime DateCreated { get; set; }
public long AlbumId { get; set; }
public virtual Album Album { get; set; }
}
public class Album {
public long Id { get; set; }
public string Name { get; set; }
public string Location { get; set; }
public DateTime DateCreated { get; set; }
public long ThumbnailId { get; set; }
public virtual Photo Thumbnail { get; set; }
public virtual ICollection<Photo> Photos { get; set; }
}
public class PhotoMap : EntityConfiguration<Photo> {
public PhotoMap()
{
this.HasRequired(p => p.Album)
.WithMany(a => a.Photos)
.HasConstraint((p, a) => p.AlbumId == a.Id);
Property(x => x.FileName).IsVariableLength().HasMaxLength(255)
.IsRequired();
Property(x => x.Caption).IsVariableLength().HasMaxLength(255);
MapSingleType(p => new {
p.Id,
SiteAlbumId = p.AlbumId,
p.FileName,
p.Caption,
p.DateCreated
})
.ToTable("Photo");
}
}
public class AlbumMap : EntityConfiguration<Album> {
public AlbumMap()
{
this.HasRequired(a => a.Thumbnail)
.WithMany()
.WillCascadeOnDelete(false)
.HasConstraint((a, p) => p.Id == a.ThumbnailId);
Property(x => x.Location).IsVariableLength().HasMaxLength(80);
Property(x => x.Name).IsVariableLength().HasMaxLength(80).IsRequired();
MapSingleType(a => new {
a.Id,
a.ThumbnailId,
a.Location,
a.Name,
a.DateCreated
})
.ToTable("Album");
}
}
This results to the following desired schema:

Resources