Creating a form on ASP.NET using two seperate models - c#

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

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.

Get and average from user input to a database?

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.

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.

entity framework couldn't deletet edit and details

I build alittke website using c# razor.
I have a model class named "clientModel".
I used crud operation using entity framework.
at first, evrything worked fine .
But when I changed the primary key of the clientModel class from "tracingNumber" to "emailAdress" I can't delete and edit the db from the website.
when I try to do this I get HTTP Error 404.0 - Not Found.
any idea??
controller:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using VicoProject___NewVersion.Models;
namespace Project___NewVersion.Controllers
{
public class ClientController : Controller
{
private ClientModelsDBContext db = new ClientModelsDBContext();
//
// GET: /Model/
public ActionResult Index()
{
return View(db.Clients.ToList());
}
//
// GET: /Model/Details/5
public ActionResult Details(int id = 0)
{
ClientModels clientmodels = db.Clients.Find(id);
if (clientmodels == null)
{
return HttpNotFound();
}
return View(clientmodels);
}
//
// GET: /Model/Create
public ActionResult Create()
{
return View();
}
//
// POST: /Model/Create
[HttpPost]
public ActionResult Create(ClientModels clientmodels)
{
if (ModelState.IsValid)
{
db.Clients.Add(clientmodels);
db.SaveChanges();
return RedirectToAction("Index", "Home");
}
return View(clientmodels);
}
//
// GET: /Model/Edit/5
public ActionResult Edit(int id = 0)
{
ClientModels clientmodels = db.Clients.Find(id);
if (clientmodels == null)
{
return HttpNotFound();
}
return View(clientmodels);
}
//
// POST: /Model/Edit/5
[HttpPost]
public ActionResult Edit(ClientModels clientmodels)
{
if (ModelState.IsValid)
{
db.Entry(clientmodels).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(clientmodels);
}
//
// GET: /Model/Delete/5
public ActionResult Delete(int id = 0)
{
ClientModels clientmodels = db.Clients.Find(id);
if (clientmodels == null)
{
return HttpNotFound();
}
return View(clientmodels);
}
//
// POST: /Model/Delete/5
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
{
ClientModels clientmodels = db.Clients.Find(id);
db.Clients.Remove(clientmodels);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
public ActionResult Search(string search)
{
var r = db.Clients.Where(t => t.emailAdress.Contains(search) || t.name.Contains(search)).ToList();
Console.Write(r);
return RedirectToAction("Search");
}
}
}
client model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
namespace Project___NewVersion.Models
{
public class ClientModels
{
[Required]
public string name { get; set;}
[Required]
[MaxLength(10, ErrorMessage = "Phone Number must be 10 numbers") , MinLength(10, ErrorMessage = "Phone Number must be 10 numbers")]
[DataType(DataType.PhoneNumber, ErrorMessage = "Invalid Phone Number")]
public String phoneNumber { get; set; }
[Key]
[Required]
[DataType(DataType.EmailAddress, ErrorMessage = "Invalid Email Address")]
public string emailAdress { get; set; }
}
public class ClientModelsDBContext : DbContext
{
static ClientModelsDBContext()
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<ClientModelsDBContext>());
}
public DbSet<ClientModels> Clients { get; set; }
}
}
the client/index view:
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.name)
</th>
<th>
#Html.DisplayNameFor(model => model.phoneNumber)
</th>
<th>
#Html.DisplayNameFor(model => model.emailAdress)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.name)
</td>
<td>
#Html.DisplayFor(modelItem => item.phoneNumber)
</td>
<td>
#Html.DisplayFor(modelItem => item.emailAdress)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.emailAdress }) |
#Html.ActionLink("Details", "Details", new { id=item.emailAdress }) |
#Html.ActionLink("Delete", "Delete", new { id=item.emailAdress})
</td>
</tr>
}
</table>
The function with the signature
public ActionResult Delete(int id = 0)
needs to be called. The parameter to this is an int. I assume since changing it the id is now a string - so the framework doesn't know which method to call.

Categories