I have a question how to solve my problem. There is a table with items. Each item has a status "open" or "closed". For instance, 9 items with "closed" status and 14 ones with "open". I need to find the difference between open and closed items (14 - 9 = 5). How can I do it with help of ViewBag? As I understood, it is required to write "count" function in controller and transmit the result to View via ViewBag. But I don't know how to write this code. The result should be shown on the View page.
Request.cs (Model):
public class Request
{
public int Id { get; set; }
public string Name { get; set; } = "";
public string Status { get; set; } = "";
}
Controller.cs:
public IActionResult Requests()
{
var Requests = _repo.GetAllRequests();
return View(Requests);
}
Repository:
public Request GetRequest(int id)
{
return _ctx.Requests.FirstOrDefault(c => c.Id == id);
}
public List<Request> GetAllRequests()
{
return _ctx.Requests.ToList();
}
View:
<div>
<table>
#foreach (var request in Model)
{
<tr>
<th>#request.Name</th>
<th>#request.Status</th>
</tr>
}
</table>
</div>
private StatisticScore()
{
var openCount =_ctx.Requests.Where(m=> m.Status == "Open").Count();
var closedCount = _ctx.Requests.Where(m=> m.Status == "Closed").Count();
ViewBag.Difference = openCount - closedCount
}
<label> Difference </label> #ViewBag.Difference
Also, I suggest you; Do not use status fields as strings. It will be easier for you if you keep it as an enum.
You would pass a predicate to Count to filter the requests by status:
public IActionResult Requests()
{
var requests = _repo.GetAllRequests();
ViewBag.OpenRequests = requests.Count(r => r.Status == "open");
ViewBag.ClosedRequests = requests.Count(r => r.Status == "closed");
return View(requests);
}
However, rather than using the ViewBag you could create a view model to hold all the information/data required by the view:
// ViewModel
public class RequestViewModel
{
public List<Request> Requests { get; set; }
public int OpenRequests { get; set; }
public int ClosedRequests { get; set; }
}
// Controller
public IActionResult Requests()
{
var requests = _repo.GetAllRequests();
var viewModel = new RequestViewModel();
viewModel.OpenRequests = requests.Count(r => r.Status == "open");
viewModel.ClosedRequests = requests.Count(r => r.Status == "closed");
viewModel.Requests = requests;
return View(viewModel);
}
// View: set the model for the view
#model Project.Namespace.RequestViewModel
...
<div>
<div>Open Requests: #model.OpenRequests</div>
<div>Closed Requests: #model.ClosedRequests</div>
<div>Difference/delta: #(model.OpenRequests - model.ClosedRequests)</div>
</div>
Related
First of all, I need to know how I can get a row from the database by some how using the URL{id} as the value that I need, to query my database for the TripId. Once I have that I then need to pass it to the view.
In my controller I was looking for the tripid value '1' just to see if I could get that displaying on my view. but i expect that is where I would have a more complex query
Any help is greatly appreciated!
This is the controller
public class TripsController : Controller
{
private ApplicationDbContext _db = new ApplicationDbContext();
ActionResult View(int id)
{
using (ApplicationDbContext _db = new ApplicationDbContext())
{
var trip = (from Trips in _db.Trips
where Trips.TripId.Equals('1')
select Trips.TripId);
if (trip == null)
{
return HttpNotFound();
} else
{
/// Code to display page?
}
}
}
}
This is my model
public class Trips
{
[Key]
[DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
public int TripId { get; set; }
public string Country { get; set; }
public string City { get; set; }
public string Description { get; set; }
public int Price { get; set; }
public DateTime Date { get; set; }
public int CoachId { get; set; }
}
}
And lastly the view..
#model _MVCCoachTravelling.Models.Trips
#{
ViewBag.Title = "View";
}
<div class="main-container">
<div class="row">
<img class="img-responsive" src="http://placehold.it/800x300" alt="">
<div class="caption-full">
<h4 class="pull-right">£#Html.DisplayFor(model => model.Price)</h4>
<h4>
#Html.DisplayFor(model => model.City)
</h4>
<p>#Html.DisplayFor(model => model.Description)</p>
</div>
If your query fails it is because you are comparing a char to an int
where Trips.TripId.Equals('1')
You should instead compare
where Trips.TripId == 1
Once you get your trip it is now return View(trip).
public ActionResult ViewTrip(int id)
{
using (ApplicationDbContext db = new ApplicationDbContext())
{
var query = from t in db.Trips
where t.TripId == id
select t;
var trip = query.FirstOrDefault();
if (trip == null) { /* fail */ }
return View(trip);
}
}
You can simply try:
ActionResult View(int id)
{
using (ApplicationDbContext _db = new ApplicationDbContext())
{
var trip = (from Trips in _db.Trips where Trips.TripId.Equals('1') select Trips.TripId);
if (trip == null)
return HttpNotFound();
return View()
}
}
Provided your view is correctly mapped to a controller and model.
i want to call Arraylist in view. I will explain my issue clearly.
My Controller Code
public ActionResult customerid()
{
List<Customer> n = (from c in db.Customers where c.IsDeleted == false select c).ToList();
var customertype = string.Empty;
for (var i = 0; i < n.Count; i++)
{
var objCustomerName = n[i].DisplayName;
var objCustomerID = n[i].CustomerID;
var objCusCreatedDate=n[i].CreatedDate;
var objNextDate = objCusCreatedDate.GetValueOrDefault().AddDays(120);
var salescount = (from sc in db.SalesOrders where sc.CustomerID==objCustomerID && sc.CreatedDate >= objCusCreatedDate && sc.CreatedDate<= objNextDate select sc.SalesOrderID).Count();
if (salescount <= 3&& salescount> 0)
{
customertype = "Exisiting Customer";
}
else if (salescount >= 3)
{
customertype = "Potential Customer";
}
else
{
customertype = "New Customer";
}
ArrayList obj = new ArrayList();
{
obj.Add(new string[] { objCustomerName, customertype, salescount.ToString()});
}
var details = obj;
}
return View();
}
My View Model
public class CustomerTypeViewModel
{
public System.Guid CustomerID { get; set; }
public string CustomerName { get; set; }
public DateTime CreatedDate { get; set; }
public string SalesCount { get; set; }
public string CustomerType { get; set; }
}
I want to call this array list in view. How I do that? That is i am generating one view based on controller code I need output same as like which is mentioned in the below image .
Wanted Output
Wanted Output
So i put all the fields (which i going to give as a column in View) in Array list. Now i want to call that Arraylist
obj.Add(new string[] { objCustomerName, customertype, salescount.ToString()});
in view . How I do that? I tried to explain my issue as per my level best. please understand my problem and tell me one solution. I am new to MVC so please help me to solve this problem.
In your controller:
List<CustomerTypeViewModel> obj = new List<CustomerTypeViewModel>();
obj.Add(new CustomerTypeViewModel(){
CustomerName = objCustomerName,
CustomerType = customertype,
SalesCount = salescount.ToString()
});
return View(obj);
In your view
#model IEnumerable<CustomerTypeViewModel>
and display values like this
#if (Model.Any()) {
foreach (var m in Model) {
#Html.DisplayFor(x => m.CustomerName)
#Html.DisplayFor(x => m.CustomerType)
}
}
I am currently working on a listbox that needs to have a function to remove/delete items from the listbox and ultimately the database. When an item(RegimeItem) is selected in the listbox, then the remove button is pressed the item is deleted from the database, that is what i want to happen.
The RequestedSelected part of the foreach statement in the RemoveExercises method of the controller is currently null, what i want to know is how do i make it so that it isn't? From what i understand is that when the item is selected in the listbox that is not recognized as RequestedSelected
Controller
[HttpGet]
public ActionResult ExerciseIndex(int? id, UserExerciseViewModel vmodel)
{
User user = db.Users.Find(id);
UserExerciseViewModel model = new UserExerciseViewModel { AvailableExercises = GetAllExercises(), RequestedExercises = ChosenExercises(user, vmodel) };
user.RegimeItems = model.RequestedExercises;
return View(model);
}
[HttpPost]
public ActionResult ExerciseIndex(UserExerciseViewModel model, string add, string remove, string send, int id, RegimeItem regimeItem)
{
User user = db.Users.Find(id);
user.RegimeItems = model.RequestedExercises;
RestoreSavedState(model);
if (!string.IsNullOrEmpty(add))
AddExercises(model, id);
else if (!string.IsNullOrEmpty(remove))
RemoveExercises(model, id);
SaveState(model);
return View(model);
}
void SaveState(UserExerciseViewModel model)
{
model.SavedRequested = string.Join(",", model.RequestedExercises.Select(p => p.RegimeItemID.ToString()).ToArray());
model.AvailableExercises = GetAllExercises().ToList();
}
void RemoveExercises(UserExerciseViewModel model, int? id)
{
foreach (int selected in model.RequestedSelected)
{
RegimeItem item = model.RequestedExercises.FirstOrDefault(i => i.RegimeItemID == selected);
if (item != null)
{
User user = db.Users.Find(id);
user.RegimeItems.Remove(item);
}
}
db.SaveChanges();
//RedirectToAction("ExerciseIndex");
}
void RestoreSavedState(UserExerciseViewModel model)
{
model.RequestedExercises = new List<RegimeItem>();
//get the previously stored items
if (!string.IsNullOrEmpty(model.SavedRequested))
{
string[] exIds = model.SavedRequested.Split(',');
var exercises = GetAllExercises().Where(p => exIds.Contains(p.ExerciseID.ToString()));
model.AvailableExercises.AddRange(exercises);
}
}
private List<Exercise> GetAllExercises()
{
return db.Exercises.ToList();
}
private List<RegimeItem> ChosenExercises(User user, UserExerciseViewModel model)
{
return db.Users
.Where(u => u.UserID == user.UserID)
.SelectMany(u => u.RegimeItems)
.ToList();
}
Models
public class User
{
public int UserID { get; set; }
public ICollection<RegimeItem> RegimeItems { get; set; }
public User()
{
this.RegimeItems = new List<RegimeItem>();
}
}
public class RegimeItem
{
public int RegimeItemID { get; set; }
public Exercise RegimeExercise { get; set; }
}
ViewModel
public class UserExerciseViewModel
{
public List<Exercise> AvailableExercises { get; set; }
public List<RegimeItem> RequestedExercises { get; set; }
public int? SelectedExercise { get; set; }
public int[] AvailableSelected { get; set; }
public int[] RequestedSelected { get; set; }
public string SavedRequested { get; set; }
}
View(Segment only)
<input type="submit" name="remove"
id="remove" value="<<" />
</td>
<td valign="top">
#Html.ListBoxFor(model => model.RequestedSelected, new MultiSelectList(Model.RequestedExercises, "RegimeItemID", "RegimeExercise.Name", Model.RequestedSelected))
</td>
UPDATE: Thanks to Chris' help i have made progress with the controller and i have updated the view also. It is still not removing individual items, it is returning a blank list and it does not save to the db either.
You're never actually persisting anything. Unless you call SaveChanges somewhere, all of what you're doing just goes away on the next request.
I am a beginner in ASP MVC, and, after a lot of help from SO, am progressing through ViewModels. Using a ViewModel however, I have encountered the following error.
Given the following View:
#model November.ViewModels.Staff_Salutation_VM
//...
using (Html.BeginForm("UpdateStaff", "Settings", FormMethod.Post,
new { #class = "clearfix parameter-form update-parameter update-staff", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
//...
#for (int i = 0; i < Model.AvailableStaffMembers.Count; i++)
{
var staff = Model.AvailableStaffMembers[i];
<tr>
<td>#Html.HiddenFor(model => staff.ID)#Html.ValueFor(model => staff.ID)</td>
<td>
#Html.DropDownListFor(
model => model.SalutationID, Model.AvailableSalutations.Select(option => new SelectListItem
{
Text = option.Desc.ToString(),
Value = option.ID.ToString(),
Selected = (option.ID.ToString() == staff.SalutationID.ToString())
}
),
"Choose...")
</td>
<td>#Html.EditorFor(model => staff.FName)</td>
<td>#Html.EditorFor(model => staff.LName)</td>
<td>#Html.EditorFor(model => staff.Active)</td>
<td>Delete</td>
</tr>
}
and the following Controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using November.Models;
using November.ViewModels;
using November.DAL;
//...
//GET
var staffCreateViewModel = new Staff_Salutation_VM();
staffCreateViewModel.AvailableSalutations = new List<Prm_Salutation>();
var activeSalts = (from a in db.Prm_Salutations
where a.Active == true
orderby a.Desc ascending
select a);
staffCreateViewModel.AvailableSalutations = activeSalts.ToList();
staffCreateViewModel.AvailableStaffMembers = new List<Prm_Staff>();
var activeStaff = (from a in db.Prm_Staffs
where a.Active == true
orderby a.LName ascending
select a);
staffCreateViewModel.AvailableStaffMembers = activeStaff.ToList();
return View("StaffMembers", staffCreateViewModel);
//POST
public ActionResult UpdateStaff(Staff_Salutation_VM list)
{
if (ModelState.IsValid)
{
foreach (var formData in list) //no longer works due to dropping List<>
{
var tbl = db.Prm_Staffs.Where(a => a.ID.Equals(formData.ID)).FirstOrDefault();
if (tbl != null)
{
var Prm_StaffModel = new Prm_Staff();
Prm_StaffModel.SalutationID = formData.SalutationID;
Prm_StaffModel.FName = formData.FName;
Prm_StaffModel.LName = formData.LName;
Prm_StaffModel.Active = formData.Active;
}
}
db.SaveChanges();
ViewBag.UpdateRtrn = "Successfully Updated.";
return RedirectToAction("Parameters", new { param = "Staff Members" });
}
else
{
ViewBag.UpdateRtrn = "Failed ! Please try again.";
return RedirectToAction("Parameters", new { param = "Staff Members" });
}
}
return RedirectToAction("Parameters", new { param = "Staff Members" });
}
And, for good measure, the ViewModel itself:
public class Staff_Salutation_VM
{
public int ID { get; set; }
public int SalutationID { get; set; }
public string FName { get; set; }
public string LName { get; set; }
public bool Active { get; set; }
public List<Prm_Salutation> AvailableSalutations { get; set; }
public List<Prm_Staff> AvailableStaffMembers { get; set; }
public Staff_Salutation_VM() { }
}
When triggered, no form values populate the ActionResult, resulting in a Object reference not set to an instance of an object. exception being thrown when the foreach (var formData in list) line is reached. Debugging shows list as being null. How can this be so? Or rather, what am I doing wrong?
EDIT: the list variable in my POST ActionResult is now getting data - or at least, is showing the various types in the class when debugged. How do I then iterate through it to save that data in the appropriate rows of the DB?
I totally missed the method signature, sorry! Your initial view load passes a model Staff_Salutation_VM but your UpdateStaff (form posted) is expecting List<Staff_Salutation_VM>. These are different animals. Change public ActionResult UpdateStaff(List<Staff_Salutation_VM> list) to public ActionResult UpdateStaff(Staff_Salutation_VM staff) just to see if you get past the null ref exception. Note, you'll need to remove your foreach since you don't have an IEnumerable coming in.
I hope this post will be helpful for you.
Model Binding To A List
Just started messing around with MVC and have been trying to accomplish this by looking at this example:
http://forums.asp.net/t/1670552.aspx
I keep getting this error:
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Line 9: #using (Html.BeginForm("Index","Home",FormMethod.Post, new{id = "ID"})){
Line 10: #Html.DropDownListFor(m=>m.id, new SelectList(Model.list, "id","name"),"selectThis")
Line 11: }
Here is the code:
Model classes (stupid names, I know):
These are in a console application used only to store models.
namespace Model
{
public class Model
{
public int id { get; set; }
public string name { get; set; }
}
public class List
{
public int id { get; set; }
public List<Model> list = new List<Model>();
}
public class subModel
{
public int id { get; set; }
public int modId { get; set; }
public string name { get; set; }
}
public class subList
{
public List<subModel> list = new List<subModel>();
}
}
Controller: (was populating subList.list and List.list with methods in the class, but decided to try it this way now, was getting the same error)
namespace DropboxTest.Controllers
{
public class HomeController : Controller
{
//
// GET: /Model/
public ActionResult Index()
{
LoadModel();
return View();
}
[ValidateInput(false)]
[AcceptVerbs("POST")]
public ActionResult Index([Bind(Exclude = "id")]Model.Model model)
{
var modId = Request["id"];
LoadModel();
LoadSubCategory(Convert.ToInt32(modId));
return View();
}
public void LoadModel()
{
Model.List listM = new Model.List();
listM.id = 0;
Model.Model mod1 = new Model.Model();
mod1.id = 1;
mod1.name = "me";
Model.Model mod2 = new Model.Model();
mod2.id = 2;
mod2.name = "me";
listM.list.Add(mod1);
listM.list.Add(mod2);
ViewBag.Model = listM;
}
public void LoadSubCategory(int id)
{
Model.subList subList = new Model.subList();
Model.subModel sub1 = new Model.subModel();
Model.subModel sub2 = new Model.subModel();
sub1.id = 1;
sub1.name = "notme";
sub1.modId = 1;
sub2.id = 1;
sub2.name = "notme";
sub2.modId = 1;
subList.list.Add(sub1);
subList.list.Add(sub2);
List<Model.subModel> sel = new List<Model.subModel>();
foreach (var item in subList.list)
{
if (item.modId == id)
{
sel.Add(item);
}
}
ViewBag.SubModel = sel;
}
}
}
View: (I have no idea if anything for subModel dropdown is working as I haven't even gotten to that part yet, but w/e.)
#model Model.List
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
#using (Html.BeginForm("Index","Home",FormMethod.Post, new{id = "ID"})){
#Html.DropDownListFor(m=>m.id, new SelectList(Model.list, "id","name"),"selectThis")
}
#if (ViewBag.SubModel != null)
{
#Html.DropDownList("SubModel",ViewBag.SubModel as SelectList, "select one")
}
It's probably something really stupid but I've been stuck for a couple of hours trying different things.
PS: This is just a test app. After I see how it is done I will be doing one with and SQL DB, using models in ConsoleApplications to retrieve and store data from the DB and display it in views, so any advice on that will be also appreciated.
A big thank you to all that have read up to here and have a nice day.
You never pass a model to the view in the controller, you just store in ViewBag.Model.
Try something as follows:
[ValidateInput(false)]
[AcceptVerbs("POST")]
public ActionResult Index([Bind(Exclude = "id")]Model.Model model)
{
var modId = Request["id"];
//get model
var model = LoadModel();
//pass it to the view
return View(model);
}