Get and average from user input to a database? - c#

I am totally new to programming so my question maybe confusing but I will try to explain as best as I can.
So I build a app that take in ratings between 1-5. The result is stored in the data base. But I do not understand how to put some logic in my model class where it can retrieve that number and out output the number the users input and the overall average of the rating it was given.
This is my Model class:
public class MovieReview : IValidatableObject
{
public int Id { get; set; }
[Range(1,10)]
[Required]
public double Rating { get; set; }
[Required]
[StringLength(1024)]
public string Comment { get; set; }
[Display(Name="User Name")]
[DisplayFormat(NullDisplayText="anonymous")]
//[MaxWord(5)]
public string ReviewerName { get; set; }
public int MovieId { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if(Rating < 2 && ReviewerName.ToLower().StartsWith("keith"))
{
yield return new ValidationResult("Scorry, Keith uou can't do this");
}
//throw new NotImplementedException();
}
}
public partial class MovieReview : IValidatableObject
{
public ICollection<AverageRating>
public int Id { get; set; }
public int AverageRating { get _AverageRating(c => c.AverageRating; set; }
}
}
This is my controller:
namespace YayOrNay.Controllers
{
public class ReviewsController : Controller
{
YayOrNayDb _db = new YayOrNayDb();
// GET: Reviews
public ActionResult Index([Bind(Prefix = "id")]int movieId)
{
var movie = _db.Movies.Find(movieId);
if(movie !=null)
{
return View(movie);
}
return HttpNotFound();
}
[HttpGet]
public ActionResult Create (int movieId)
{
return View();
}
[HttpPost]
public ActionResult Create(MovieReview review)
{
if(ModelState.IsValid)
{
_db.Reviews.Add(review);
_db.SaveChanges();
return RedirectToAction("Index", new { id = review.MovieId });
}
return View(review);
}
[HttpGet]
public ActionResult Edit (int id)
{
var model = _db.Reviews.Find(id);
return View(model);
}
//[Bind(Exclude = "ReviewerName")]
[HttpPost]
public ActionResult Edit (MovieReview review)
{
if (ModelState.IsValid)
{
_db.Entry(review).State = EntityState.Modified;
_db.SaveChanges();
return RedirectToAction("Index", new { id = review.MovieId });
}
return View(review);
}
protected override void Dispose(bool disposing)
{
_db.Dispose();
base.Dispose(disposing);
}
}
}
And this is my view:
#model IEnumerable<YayOrNay.Models.MovieReview>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Rating)
</th>
<th>
#Html.DisplayNameFor(model => model.Comment)
</th>
<th>
#Html.DisplayNameFor(model => model.ReviewerName)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Rating)
</td>
<td>
#Html.DisplayFor(modelItem => item.Comment)
</td>
<td>
#Html.DisplayFor(modelItem => item.ReviewerName)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
</td>
</tr>
}
</table>
I hope this is enough information for you to understand what I am trying to do.

Related

C# - MVC - How to list multiple entries based on one foreign key

This is my first post so I apologize for my lack of awareness.
I am trying to select a number of items linked to a category, based on the selected categories ID. I know I need to somehow utilize the created list in the model, but I am not sure how.
In other words, I want to list Menu Items on the Category "Details" view, based on which category is selected on the site.
MenuCategory Model
public class MenuCategory
{
public int MenuCategoryId
{
get;
set;
}
public string Name
{
get;
set;
}
public List<MenuItem> MenuItems
{
get;
set;
}
}
MenuItem Model
public class MenuItem
{
public int MenuItemId
{
get;
set;
}
public string Name
{
get;
set;
}
public string Image
{
get;
set;
}
[ForeignKey("MenuCategory")]
public int MenuCategoryId
{
get;
set;
}
public MenuCategory MenuCategory
{
get;
set;
}
}
MenuCategory View Index
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
<a asp-controller="MenuCategories" asp-action="Details" asp-route-id="#item.MenuCategoryId">
Details
</a>
</td>
</tr>
}
</tbody>
MenuCategory Details View
#model Farbucks.Models.MenuCategory
#{
ViewData["Title"] = "Details";
}
<h2>Details</h2>
<div>
<h4>MenuCategory</h4>
<hr />
<dl class="dl-horizontal">
<dt>
#Html.DisplayNameFor(model => model.Name)
</dt>
</dl>
</div>
#foreach (var item in Model.MenuItems)
{
#Html.DisplayFor(modelItem => item.Name)
}
MenuCategories Controller
{
public class MenuCategoriesController : Controller
{
private readonly ApplicationDbContext _context;
public MenuCategoriesController(ApplicationDbContext context)
{
_context = context;
}
// GET: MenuCategories
public async Task<IActionResult> Index()
{
return View(await _context.MenuCategory.ToListAsync());
}
// GET: MenuCategories/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var menuCategory = await _context.MenuCategory
.FirstOrDefaultAsync(m => m.MenuCategoryId == id);
if (menuCategory == null)
{
return NotFound();
}
return View(menuCategory);
}
}
}
MenuItems Controller
{
public class MenuItemsController : Controller
{
private readonly ApplicationDbContext _context;
public MenuItemsController(ApplicationDbContext context)
{
_context = context;
}
// GET: MenuItems
public async Task<IActionResult> Index()
{
var applicationDbContext = _context.MenuItem.Include(m => m.MenuCategory);
return View(await applicationDbContext.ToListAsync());
}
// GET: MenuItems/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var menuItem = await _context.MenuItem
.Include(m => m.MenuCategory)
.FirstOrDefaultAsync(m => m.MenuItemId == id);
if (menuItem == null)
{
return NotFound();
}
return View(menuItem);
}
}
}
In MenuCategory Details View, You can get list of MenuItems by using Lazy loading in entity
So it looks like the snipped below:
MenuCategory Details View
foreach(var item in Model.MenuItems)
{
// display information of Menu item here.
}

edit.cshtml returning Error HTTP 404 in mvc5 razor

I wanted to redirect "Edit" Actionlink to a another page from Index.cshtml page and the directions in the tab shows "http://localhost:49712/Home/Edit/id". The data are shown in "Index.cshtml" in a table but not all data is shown (just some of it). Then, when I want to edit the data, the edit page shows "HTTP Error 404.0 - Not Found". I think this is because of the attributes got clash or anything?
This is the "Index.cshtml" for the table:-
foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.ID)
</td>
<td>
#Html.DisplayFor(modelItem => item.NUMBER)
</td>
<td>
#Html.DisplayFor(modelItem => item.TITLE)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.ID}) |
#Html.ActionLink("Details", "Details", new { id = item.ID}) |
#Html.ActionLink("Delete", "Delete", new { id = item.ID})
</td>
</tr>
}
This is the edit part in controller":-
// GET: Home/Edit/5
public async Task<ActionResult> Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Tests test= await db.Test.FindAsync(id);
if (test== null)
{
return HttpNotFound();
}
return View(test);
}
// POST: Home/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "ID,YEAR,LANGUAGE,COUNTRY,SUBJECT,NUMBER,TITLE] Tests test)
{
if (ModelState.IsValid)
{
db.Entry(test).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(test);
}
This is my model:-
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class Tests
{
public string ID{ get; set; }
public Nullable<int> YEAR { get; set; }
public string LANGUAGE { get; set; }
public string COUNTRY { get; set; }
public string SUBJECT { get; set; }
public string NUMBER { get; set; }
public string TITLE { get; set; }
}
}
As you can see, some of the attributes does not shown in data table in "Index.cshtml", but all of them will be shown in edit page. How can I do this? Any help from anyone would be highly appreciated.

Creating a form on ASP.NET using two seperate models

I am using Visual Studio 2017 with everything up to the most recent updates.
I'm trying to enter in a form with some normal text box answer questions as well as a checkbox answer question, and have all answers be recorded in the same database. Part of my issue is how do I get two separate models asking separate questions using separate databases as references for those questions into one single controller and a view with a list of all of the question answers in one database record? Perhaps I am going about this the wrong way, as I am new to ASP.NET this is highly likely. Any input to this issue would be greatly appreciated…
Below is the code for my two models:
Model I:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace TessituraForm
{
public class TessituraFormContext : DbContext
{
public TessituraFormContext(DbContextOptions<TessituraFormContext> options) : base(options)
{
}
public DbSet<Models.Roles> Roles { get; set; }
}
}
Model II:
using System;
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;
namespace TessituraForm.Models
{
public class Applicant
{
public int ID { get; set; }
[Display(Name = "Full Name:")]
[DataType(DataType.Text)]
[Required]
public string FullName { get; set; }
[Display(Name = "SI User Name:")]
[StringLength(10)]
[DataType(DataType.Text)]
[Required]
public string SIUserName { get; set; }
[Display(Name = "Supervisor:")]
[Required]
public string Supervisor { get; set; }
[Display(Name = "Badge Number:")]
[StringLength(8)]
[DataType(DataType.Text)]
[Required]
public string BadgeNumber { get; set; }
[Display(Name = "Badge Expiration Date:")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM-dd-yyyy}", ApplyFormatInEditMode = true)]
[Required]
public DateTime BadgeExpirationDate { get; set; }
[Display(Name = "Applicant is a(n):")]
[DataType(DataType.Text)]
[Required]
public string ApplicantIsAn { get; set; }
}
public class Roles
{
[Key]
public int ID { get; set; }
public string AdvancementFundraising { get; set; }
public string CustomerService { get; set; }
public string DiscoveryTheater { get; set; }
public string BusinessOffice { get; set; }
public string CustomerServiceSupport { get; set; }
public string ExecutiveStaff { get; set; }
public string Marketing { get; set; }
public string Programming { get; set; }
public string VolunteerCoordinator { get; set; }
public bool CheckboxAnswer { get; set; }
}
}
Controller Code:
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Threading.Tasks;
using TessituraForm.Models;
namespace Applicant.Controllers
{
public class ApplicantController : Controller
{
private readonly TessituraFormContext _context;
public ApplicantController(TessituraFormContext context)
{
_context = context;
}
// GET: Applicants
public async Task<IActionResult> Index()
{
return View(await _context.Applicant.ToListAsync());
}
// GET: Applicants/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var applicant = await _context.Applicant
.SingleOrDefaultAsync(m => m.ID == id);
if (applicant == null)
{
return NotFound();
}
return View(applicant);
}
// GET: Applicants/Create
public IActionResult Create()
{
return View();
}
// POST: Applicants/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID,FullName,SIUserName,Supervisor,BadgeNumber,BadgeExpirationDate,ApplicantIsAn,Roles")] Applicant applicant)
{
if (ModelState.IsValid)
{
_context.Add(applicant);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(applicant);
}
// GET: Applicants/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var applicant = await _context.Applicant.SingleOrDefaultAsync(m => m.ID == id);
if (applicant == null)
{
return NotFound();
}
return View(applicant);
}
// POST: Applicants/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,FullName,SIUserName,Supervisor,BadgeNumber,BadgeExpirationDate,ApplicantIsAn,Roles")] Applicant applicant)
{
if (id != applicant.ID)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(applicant);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ApplicantExists(applicant.ID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction("Index");
}
return View(applicant);
}
// GET: Applicants/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var applicant = await _context.Applicant
.SingleOrDefaultAsync(m => m.ID == id);
if (applicant == null)
{
return NotFound();
}
return View(applicant);
}
// POST: Applicants/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var applicant = await _context.Applicant.SingleOrDefaultAsync(m => m.ID == id);
_context.Applicant.Remove(applicant);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
private bool ApplicantExists(int id)
{
return _context.Applicant.Any(e => e.ID == id);
}
}
}
namespace DatabaseContext.Controllers
{
public class DatabaseContextController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Roles()
{
Applicant objApplicant = newApplicant();
}
}
}
And View Index Code:
#model IEnumerable<TessituraForm.Models.Applicant>
#{
ViewData["Title"] = "Index";
}
<style>
body {
background-color: lightgray;
}
h2 {
color: black;
margin-left: 5px;
}
</style>
<img src="~/Images/TSA.jpg" alt="TSA" style="position:absolute;left:1372px;top:57px;width:150px;height:75px;" />
<h2>Index</h2>
<p>
<a asp-action="Create" style="margin-left:20px;">Create New</a>
</p>
<table class="table" border="1">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.FullName)
</th>
<th>
#Html.DisplayNameFor(model => model.SIUserName)
</th>
<th>
#Html.DisplayNameFor(model => model.Supervisor)
</th>
<th>
#Html.DisplayNameFor(model => model.BadgeNumber)
</th>
<th>
#Html.DisplayNameFor(model => model.BadgeExpirationDate)
</th>
<th>
#Html.DisplayNameFor(model => model.ApplicantIsAn)
</th>
<th>
#Html.DisplayNameFor(model => model.Roles)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.FullName)
</td>
<td>
#Html.DisplayFor(modelItem => item.SIUserName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Supervisor)
</td>
<td>
#Html.DisplayFor(modelItem => item.BadgeNumber)
</td>
<td>
#Html.DisplayFor(modelItem => item.BadgeExpirationDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.ApplicantIsAn)
</td>
<td>
#Html.DisplayFor(modelItem => item.Roles)
</td>
<td>
<a asp-action="Edit" asp-route-id="#item.ID">Edit</a> |
<a asp-action="Details" asp-route-id="#item.ID">Details</a> |
<a asp-action="Delete" asp-route-id="#item.ID">Delete</a>
</td>
</tr>
}
</tbody>
</table>
Again, my goal is simply to have a form on the web page that has a section with normal text box answers and a checkbox section as well. Any help is much appreciated.
What you can do is to create a new Model and then place the other two in that one like below:
public class YourNewModel
{
public Applicant Applicant {get;set;} //note you can declare it here as a List or any how you want
public Roles Roles {get;set;}
}
Note
This is just to give you an idea and start you have of, it will also mean changing the methods in your Controller suit the approach.
You will also have to pass this Model to your view, this way you can have both models at the same place like you wanted.
I hope this helps

How To Restrict User Entries Only to that Sepcific User in EF 6/ASP.NET MVC 5

I am trying to restrict user entries so that only that specific user is able to see their entries and not anyone else. In other words, after all I've done, my application still displays every entry that was ever entered; and any user is able to see the entries.
I've created a one-to-many relationship by referencing the foreign key from my Expenses table to the primary key of my AspNetUsers using the Code First convention in Entity Framework, however, when I log in as different users, I am still able to see entries (expenses) that other users have entered.
I'm not sure whether the problem lies in my view, model, or controller.
Here is the code I currently have:
IdentityModel:
public class ApplicationUser : IdentityUser
{
public ApplicationUser()
{
Expenses = new List<Expense>();
}
[Required]
public string Fullname { get; set; }
[Required]
public string Province { get; set; }
[Required]
public string Company { get; set; }
public virtual ICollection<Expense> Expenses { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("PacificPetEntities", throwIfV1Schema: false)
{
}
public IDbSet<Expense> Expenses { get; set; }
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
Expense Model:
public class Expense : IValidatableObject
{
public Expense() { }
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[Required]
public string Category { get; set; }
public string Description { get; set; }
[Required]
[Display(Name = "Gross Amount")]
public double GrossAmount { get; set; }
[Required]
[Display(Name = "Tax Amount")]
public double TaxAmount { get; set; }
[Required]
[Display(Name = "Net Amount")]
public double NetAmount { get; set; }
public int Mileage { get; set; }
[Display(Name = "Mileage Rate")]
public double MileageRate { get; set; }
[Required]
[Display(Name = "Date Submitted")]
public DateTime? DateSubmitted { get; set; }
[Required]
[Display(Name = "Expense Date")]
public DateTime? ExpenseDate { get; set; }
public string UserId { get; set; }
[ForeignKey("UserId")]
public virtual ApplicationUser ApplicationUser { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Category == "Auto - Mileage" && Mileage == 0)
{
yield return new ValidationResult("You must enter a mileage amount if the chosen category is mileage.");
}
}
}
Controller:
public class ExpensesController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
// GET: Expenses
[Authorize]
public ActionResult Index()
{
var expenses = db.Expenses.Include(e => e.ApplicationUser);
return View(expenses.ToList());
}
// GET: Expenses/Details/5
[Authorize]
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Expense expense = db.Expenses.Find(id);
if (expense == null)
{
return HttpNotFound();
}
return View(expense);
}
// GET: Expenses/Create
[Authorize]
public ActionResult Create()
{
ViewBag.UserId = new SelectList(db.Users, "Id", "Fullname");
return View();
}
// POST: Expenses/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize]
public ActionResult Create([Bind(Include = "ID,Category,Description,GrossAmount,TaxAmount,NetAmount,Mileage,MileageRate,DateSubmitted,ExpenseDate,UserId")] Expense expense)
{
if (ModelState.IsValid)
{
db.Expenses.Add(expense);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.UserId = new SelectList(db.Users, "Id", "Fullname", expense.UserId);
return View(expense);
}
// GET: Expenses/Edit/5
[Authorize]
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Expense expense = db.Expenses.Find(id);
if (expense == null)
{
return HttpNotFound();
}
ViewBag.UserId = new SelectList(db.Users, "Id", "Fullname", expense.UserId);
return View(expense);
}
// POST: Expenses/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize]
public ActionResult Edit([Bind(Include = "ID,Category,Description,GrossAmount,TaxAmount,NetAmount,Mileage,MileageRate,DateSubmitted,ExpenseDate,UserId")] Expense expense)
{
if (ModelState.IsValid)
{
db.Entry(expense).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.UserId = new SelectList(db.Users, "Id", "Fullname", expense.UserId);
return View(expense);
}
// GET: Expenses/Delete/5
[Authorize]
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Expense expense = db.Expenses.Find(id);
if (expense == null)
{
return HttpNotFound();
}
return View(expense);
}
// POST: Expenses/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
[Authorize]
public ActionResult DeleteConfirmed(int id)
{
Expense expense = db.Expenses.Find(id);
db.Expenses.Remove(expense);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
Index.cshtml:
#model IEnumerable<PacificPetExpenses.Models.Expense>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.ApplicationUser.Fullname)
</th>
<th>
#Html.DisplayNameFor(model => model.Category)
</th>
<th>
#Html.DisplayNameFor(model => model.Description)
</th>
<th>
#Html.DisplayNameFor(model => model.GrossAmount)
</th>
<th>
#Html.DisplayNameFor(model => model.TaxAmount)
</th>
<th>
#Html.DisplayNameFor(model => model.NetAmount)
</th>
<th>
#Html.DisplayNameFor(model => model.Mileage)
</th>
<th>
#Html.DisplayNameFor(model => model.MileageRate)
</th>
<th>
#Html.DisplayNameFor(model => model.DateSubmitted)
</th>
<th>
#Html.DisplayNameFor(model => model.ExpenseDate)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.ApplicationUser.Fullname)
</td>
<td>
#Html.DisplayFor(modelItem => item.Category)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#Html.DisplayFor(modelItem => item.GrossAmount)
</td>
<td>
#Html.DisplayFor(modelItem => item.TaxAmount)
</td>
<td>
#Html.DisplayFor(modelItem => item.NetAmount)
</td>
<td>
#Html.DisplayFor(modelItem => item.Mileage)
</td>
<td>
#Html.DisplayFor(modelItem => item.MileageRate)
</td>
<td>
#Html.DisplayFor(modelItem => item.DateSubmitted)
</td>
<td>
#Html.DisplayFor(modelItem => item.ExpenseDate)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
#Html.ActionLink("Details", "Details", new { id=item.ID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
</tr>
}
</table>
Please help.
Thank you.
Select your Expenses with the current user id. Like this.
// GET: Expenses
[Authorize]
public ActionResult Index()
{
var expenses = db.Expenses.Where(e => e.UserId == User.Identity.GetUserId());
return View(expenses.ToList());
}
I have found the answer. Padhraic was really close, but his answer helped me solve my problem.
In my controller, I had:
public ActionResult Index()
{
var expenses = db.Expenses.Include(e => e.ApplicationUser);
return View(expenses.ToList());
}
Instead, this should be:
public ActionResult Index()
{
string currentUserId = User.Identity.GetUserId();
var expenses = db.Expenses.Where(e => e.UserId == currentUserId);
return View(expenses.ToList());
}
According to Stephen Muecke's comment on my question, db.Expenses.Include(e => e.ApplicationUser) was returning all rows in my database. Instead I needed to filter the results to the current user.

How to pass complex object collections to the controller in mvc

I'm new to MVC and sorry for this beginners question. I have following Model classes:
public class ReturnBookHedModel
{
public int RefferenceID { get; set; }
public int BorrowedRefNo { get; set; }
public int MemberId { get; set; }
public DateTime ReturnDate { get; set; }
public bool IsNeedToPayFine { get; set; }
public DateTime CurrentDate { get; set; }
public virtual List<ReturnBookDetModel> RetunBooks { get; set; }
public virtual MemberModel member { get; set; }
}
public class ReturnBookDetModel
{
public int BookID { get; set; }
public int RefferenceID { get; set; }
public bool IsReturned { get; set; }
public virtual ReturnBookHedModel ReturnBookHed { get; set; }
public virtual BookModel book { get; set; }
}
I have following controller methods:
public ActionResult SaveReturnBook(int refNo)
{
ReturnBookHedModel model = ReturnBookFacade.GetReturnBookBasedOnRefference(refNo);
return View(model);
}
//
// POST: /ReturnBook/Create
[HttpPost]
public ActionResult SaveReturnBook(ReturnBookHedModel model)
{
try
{
// TODO: Add insert logic here
return RedirectToAction("Index");
}
catch
{
return View();
}
}
in my model i define as follows:
<div class="control-label">
#Html.LabelFor(model => model.BorrowedRefNo)
#Html.TextBoxFor(model => model.BorrowedRefNo, new { #class = "form-control" ,#readonly = "readonly" })
#Html.ValidationMessageFor(model => model.BorrowedRefNo)
</div>
// rest of the header details are here
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.RetunBooks.FirstOrDefault().IsReturned)
</th>
<th>
#Html.DisplayNameFor(model => model.RetunBooks.FirstOrDefault().BookID)
</th>
<th>
#Html.DisplayNameFor(model => model.RetunBooks.FirstOrDefault().book.BookName)
</th>
<th></th>
</tr>
#foreach (var item in Model.RetunBooks)
{
<tr >
<td>
#Html.CheckBoxFor(modelItem => item.IsReturned)
</td>
<td>
#Html.HiddenFor(modelItem => item.BookID);
#Html.DisplayFor(modelItem => item.BookID)
</td>
<td>
#Html.DisplayFor(modelItem => item.book.BookName)
</td>
</tr>
}
</table>
this is working fine.. but these table details (complex objects) are not in the controller's post method. when i searched i found that i can use this detail data as follows: but i cant use it as follows.
#for (var i = 0; i < Model.RetunBooks.Count; i++)
{
<tr>
<td>
#Html.CheckBoxFor(x => x.RetunBooks.)
</td>
</tr>
}
how can i send these information to controller
In order for the collection to be posted back you need to index them in the following way for the model binder to pick them up.
This should do the trick:
#for (var i = 0; i < Model.RetunBooks.Count; i++)
{
...
#Html.CheckBoxFor(model => Model.RetunBooks[i].IsReturned)
...
}
Complex objects require the indexing in the above manner.
For more info on it see here:
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/

Categories