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
Related
I want to set default value for an EditorFor HTML helper but just the helper text is displayed in it. Why EditorFor does not let me to set its default value, please?
class Person {
public int Id { get; set; }
public DateTime DateOfBirth { get; set; }
...
}
class PersonVM {
public Person { get; set; }
...
}
public ActionResult Edit(int id)
{
var vm = new PersonVM ();
vm.Person = db.Persons.Where(x => x.Id == id).FirstOrDefault();
...
return View(vm);
}
#model Project.Models.PersonVM
#Html.EditorFor(model => model.Person.DateOfBirth , new { htmlAttributes = new { #class = "form-control" } })
Set the default value by assigning a value to the model property.
Either in the Controller Action:
public ActionResult Edit(int id) {
var vm = new PersonVM ();
vm.Person = db.Persons.Where(x => x.Id == id).FirstOrDefault();
if (vm.Person.DateOfBirth == default(DateTime)) {
vm.Person.DateOfBirth = new DateTime(1900, 01, 01); // default value
}
// ...
return View(vm);
}
Or in the ViewModel (make sure that you only map valid DateOfBirth from the DB to the ViewModel):
public class PersonVM {
public PersonViewModel () {
DateOfBirth = new DateTime(1900, 01, 01); // default value
}
public int Id { get; set; }
public DateTime DateOfBirth { get; set; }
// ...
}
I'm trying to include a search functionality in a ASP.NET Web Application using a search textbox. I have a controller (HomeController) which include an Index (list all data) and a Search (based on user input) Action Method but I'm having trouble writing the code/query for the Search Action Method. Any help would be appreciated. Thanks
//textbox from the View
#using (Html.BeginForm("Search", "Home"))
{
#Html.Editor("SearchBox")
<input type="submit" value="Search" />
}
//The model
public class EventViewModel
{
public int Id { get; set; }
public string Title { get; set; }
public DateTime StartDateTime { get; set; }
public TimeSpan? Duration { get; set; }
public string Author { get; set; }
public string Location { get; set; }
public static Expression<Func<Event, EventViewModel>> ViewModel
{
get
{
return e => new EventViewModel()
{
Id = e.Id,
Title = e.Title,
StartDateTime = e.StartDateTime,
Duration = e.Duration,
Location = e.Location,
Author = e.Author.FullName
};
}
}
}
public class UpcomingPassedEventsViewModel
{
public IEnumerable<EventViewModel> UpcomingEvents { get; set; }
public IEnumerable<EventViewModel> PassedEvents { get; set; }
}
//controller
public class HomeController : BaseController
{
public ActionResult Index()
{
var events = this.db.Events
.OrderBy(e => e.StartDateTime)
.Where(e => e.IsPublic)
.Select(EventViewModel.ViewModel);
var upcomingEvents = events.Where(e => e.StartDateTime > DateTime.Now);
var passedEvents = events.Where(e => e.StartDateTime <= DateTime.Now);
return View(new UpcomingPassedEventsViewModel()
{
UpcomingEvents = upcomingEvents,
PassedEvents = passedEvents
});
}
public ActionResult Search(string SearchBox)
{
}
I've used Kendo Grid for showing data.It seems data is passed correctly because when I tracing my code in run time, I see there are some data in result but Kendo Grid couldn't show the data.
How can I solve this problem?
EDIT DESCRIPTION:
I found cause of problem but I cannot solve it.
If I remove this line in my ViewModel in QueryBuilder() method,
Tags = article.ArticleTags.Where(c => c.ArticleId == article.Id).Select(b => b.Tag).Distinct().ToList()
Grid show data but I need values of Tags. why this line of code has been caused the problem?
Tag model:
public class Tag : Entity, ITag
{
public Tag()
{
}
public virtual string Title { get; set; }
public virtual string Description { get; set; }
public virtual bool? IsActive { get; set; }
[Range(1, 4)]
public virtual int Size { get; set; }
public virtual ISet<ArticleTag> ArticleTags { get; set; }
public virtual ISet<ProjectTag> ProjectTags { get; set; }
}
my grid:
#using Jahan.Blog.Web.Mvc.HtmlHelpers
#using Kendo.Mvc.UI
#using Kendo.Mvc.UI.Fluent
#model IEnumerable<Jahan.Blog.ViewModel.ArticleViewModel>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<div style="width: 100%;">
#(Html.Kendo().Grid<Jahan.Blog.ViewModel.ArticleViewModel>()
.Name("ArticleAdmin").Navigatable()
.Resizable(c => c.Columns(true))
.HtmlAttributes(new { #class = "cursorLink", #style = "width: 1000px;height:auto;overflow: scroll;" })
.Columns(columns =>
{
columns.Bound(p => p.Id).Width(100);
columns.Bound(p => p.Title).Width(200);
columns.Command(command => command.Destroy()).Width(170);
})
.ToolBar(toolbar =>
{
toolbar.Create();
toolbar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Pageable()
.Navigatable()
.Sortable()
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.PageSize(10)
.ServerOperation(false)
.Events(events => events.Error("error_handler"))
.Model(model => model.Id(p => p.Id))
.Create("Editing_Create", "ArticleAdmin")
.Read("Editing_Read", "ArticleAdmin")
.Update("Editing_Update", "ArticleAdmin")
.Destroy("Editing_Destroy", "ArticleAdmin")
))
</div>
in my Controller:
public ActionResult Index([DataSourceRequest] DataSourceRequest request)
{
List<ArticleViewModel> instance = new ArticleViewModel().FindByCriteria().ToList();
return View(instance); // There are some data. instance.count = 2
}
public ActionResult Editing_Read([DataSourceRequest] DataSourceRequest request)
{
List<ArticleViewModel> instance = new ArticleViewModel().FindByCriteria().ToList();
DataSourceResult dsRequest = instance.ToDataSourceResult(request); // There are some data.
return Json(dsRequest, JsonRequestBehavior.AllowGet);
}
my ViewModel:
public class ArticleViewModel : IArticle, IDateTracking
{
public ArticleViewModel()
{
}
public int? UserId { get; set; }
public string Title { get; set; }
public string Summary { get; set; }
public string Description { get; set; }
public decimal? RateCounter { get; set; }
public int? LikeCounter { get; set; }
public bool IsActive { get; set; }
public bool IsActiveNewComment { get; set; }
public IList<Comment> Comments { get; set; }
public ISet<Rating> Ratings { get; set; }
public IList<AttachmentFile> AttachmentFiles { get; set; }
public ISet<ArticleTag> ArticleTags { get; set; }
public ISet<ArticleLike> ArticleLikes { get; set; }
public int Id { get; set; }
public DateTime? CreatedDate { get; set; }
public DateTime? ModifiedDate { get; set; }
[UIHint("_TagsOfArticle")]
public virtual IList<Tag> Tags { get; set; }
public virtual int NumberOfComments { get; set; }
public virtual User User { get; set; }
private IQueryable<ArticleViewModel> QueryBuilder()
{
ArticleRepository repository = new ArticleRepository();
IQueryable<ArticleViewModel> query = repository.FindAll().Select(article => new ArticleViewModel
{
Id = article.Id,
AttachmentFiles = article.AttachmentFiles.Where(a => a.ArticleId == article.Id).Distinct().ToList(),
Comments = article.Comments.Where(c => c.ArticleId == article.Id).ToList(),
CreatedDate = article.CreatedDate,
//Description = article.Description,
IsActive = article.IsActive,
IsActiveNewComment = article.IsActiveNewComment,
LikeCounter = article.LikeCounter,
ModifiedDate = article.ModifiedDate,
NumberOfComments = article.Comments.Count(c => c.ArticleId == article.Id),
RateCounter = article.RateCounter,
//Summary = article.Summary,
Tags = article.ArticleTags.Where(c => c.ArticleId == article.Id).Select(b => b.Tag).Distinct().ToList(),
Title = article.Title,
UserId = article.UserId
});
return query;
}
public virtual IQueryable<ArticleViewModel> QueryBuilderByCriteria(Expression<Func<ArticleViewModel, bool>> predicate = null, params Expression<Func<ArticleViewModel, object>>[] includeProperties)
{
IQueryable<ArticleViewModel> items = QueryBuilder();
if (includeProperties != null)
{
foreach (Expression<Func<ArticleViewModel, object>> includeProperty in includeProperties)
{
items = items.Include(includeProperty);
}
}
if (predicate != null)
return items.Where(predicate);
return items;
}
public virtual IEnumerable<ArticleViewModel> FindByCriteria(Expression<Func<ArticleViewModel, bool>> predicate = null, params Expression<Func<ArticleViewModel, object>>[] includeProperties)
{
List<ArticleViewModel> result = QueryBuilderByCriteria(predicate, includeProperties).ToList();
return result;
}
public virtual ArticleViewModel FindByArticleId(int articleId)
{
ArticleViewModel result = QueryBuilder().FirstOrDefault(a => a.Id == articleId);
return result;
}
}
For solving the problem I performed some changes.
1) Instead of using Tag model, I've used TagViewModel.I've figured out Tag model, itself is cause of problem! I don't know why does it cause. Then I decided to create a TagViewModel that it has simplified of Tag class.
public class TagGridViewModel
{
public virtual int Id { get; set; }
public virtual string Title { get; set; }
public virtual string Description { get; set; }
public virtual bool? IsActive { get; set; }
public virtual int Size { get; set; }
public static List<TagGridViewModel> GetByArticleId(int articleId)
{
List<TagGridViewModel> tags = new List<TagGridViewModel>();
List<Tag> tagsPerArticle = ArticleRepository.Instance.GetTagsByArticleId(articleId);
foreach (var tag in tagsPerArticle)
{
tags.Add(new TagGridViewModel
{
Id = tag.Id,
IsActive = tag.IsActive,
Description = tag.Description,
Title = tag.Title,
Size = tag.Size
});
}
return tags;
}
}
And in ArticleViewModel:
public List<TagGridViewModel> Tags { get; set; }
And in FindByCriteria method:
public virtual IEnumerable<ArticleViewModel> FindByCriteria(Expression<Func<ArticleViewModel, bool>> predicate = null, params Expression<Func<ArticleViewModel, object>>[] includeProperties)
{
List<ArticleViewModel> result = new List<ArticleViewModel>();
var query = QueryBuilderByCriteria(predicate, includeProperties);
foreach (var articleViewModel in query)
{
articleViewModel.Tags = TagGridViewModel.GetByArticleId(articleViewModel.Id);
articleViewModel.Owner = AppUserStore.Instance.FindByIdAsync(int.Parse(articleViewModel.UserId.ToString())).Result.UserName;
result.Add(articleViewModel);
}
return result;
}
After these changes, Grid shows data.
I'm currently using a ViewBag to pass data to the DropDown list.
I want to use a model instead but I can't get it to work. Here is what I have :
public ActionResult Index(int? catID)
{
GiftListItems viewModel = new GiftListItems
{
Categories = **how do I use this property for DropDown list ?**
};
// using this for DropDown list now :
var query = _categoryRepository.Table
.Select(x => new { x.Id, x.Name })
.Distinct()
.OrderBy(x => x.Name);
ViewBag.Values = new SelectList(query.AsEnumerable(), "Id", "Name");
return View(viewModel);
}
In View :
#Html.DropDownList("catID", (SelectList)ViewBag.Values, new { onchange = "this.form.submit();" })
Model :
public class GiftListItems
{
public IEnumerable<Category> Categories { get; set; }
}
Is this easy to do? Thanks
public class Model
{
public int SelectedItem{get;set;}
public IList<DropDownObj> ListObj{get;set;
public IList<SelectListItem> SelectListItemListObj{get;set;}
{
get
{
var list = (from item in ListObj
select new SelectListItem()
{
Text = item.Id.ToString(CultureInfo.InvariantCulture),
Value item.Name
}).ToList();
return list;
}
set{}
}
}
public class DropDownObj
{
public int Id{get;set;}
public string Name{get;set;
}
usage:
#Html.DropDownListFor(c=>c.SelectedItem,Model.SelectListItemListObj)
Example:
Models:
public class VmSysCategoryModel
{
public int Id { get; set; }
public string Name { get; set; }
}
public class GiftListItemsDropDown
{
public int SelectedCategoryId { get; set; }
public IEnumerable<VmSysCategoryModel> Categories { get; set; }
public IList<SelectListItem> SelectListItemListObj
{
get
{
var list = (from item in Categories
select new SelectListItem()
{
Text = item.Id.ToString(CultureInfo.InvariantCulture),
Value=item.Name
}).ToList();
return list;
}
set { }
}
}
Controller:
public ActionResult Index(int? catID)
{
var listCategories = _categoryRepository.Table
.Select(x => new {x.Id, x.Name})
.Distinct()
.OrderBy(x => x.Name);
var obj = new GiftListItemsDropDown()
{
Categories = Mapper.Map<IList<listCategories>, IList<VmSysCategoryModel>>(listCategories)
//here you mast to map from domain to viewmodel
};
return View(obj);
}
View:
#model GiftListItemsDropDown
#Html.DropDownListFor(c=>c.SelectedCategoryId ,Model.SelectListItemListObj)
You can use the view model like this -
public ActionResult NewsEdit(int ID, dms_New dsn)
{
var query = _categoryRepository.Table
.Select(x => new { x.Id, x.Name })
.Distinct()
.OrderBy(x => x.Name)).ToList();
GiftListItems viewModel = new GiftListItems
{
Categories = query.Select(x => new SelectListItem
{
Value = x.ID.ToString(),
Text = x.Name
})
};
return View(viewModel);
}
and in your view -
#model GiftListItems
#Html.DropDownList(
"catID",
Model.Categories,
new { onchange = "this.form.submit();" }
)
And your View model now should look like this -
public class GiftListItems
{
public IEnumerable<SelectListItem> Categories { get; set; }
// public IEnumerable<Category> Categories { get; set; } --
}
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:
var 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.IEnumerable1[WHFM.ViewModels.ProfitAndCostViewModel]'.`
It looks like your view is strongly typed to IEnumerable<ProfitAndCostViewModel>:
#model IEnumerable<ProfitAndCostViewModel>
but here you are passing a single ProfitAndCostViewModel instance to it:
var pcv = new ProfitAndCostViewModel();
pcv.ProfModel =getProfitSum();
pcv.CostModel =getCostSum();
return View(pcv);
So you should fix the model to which your view is typed:
#model ProfitAndCostViewModel