Variables from one table display along side another in the view - c#

Hi there I was looking for a way to select certain fields from the different database tables and output it into one table in the view.This is the code I have so far although it is only able to retrieve information from the patients table. Any help would be greatly appreciated thanks.
model
namespace ChampPMS.Models
{
public class Patient
{
public int PatientID { get; set; }
public string HouseChartNo { get; set; }
public string ClinicChartNo { get; set; }
public string Title { get; set; }
public string FirstName { get; set; }
public DateTime DOB { get; set; }
Dont think this is right.
//Other Table variables
public Admission ExpectedDate { get; set; } ------->from bed
public Beds Bed { get; set; } ------->from admissions
}
public class Beds
{
public int BedID { get; set; }
public int RoomID { get; set; }
public string Bed { get; set; }
}
public class Admission
{
public int AdmissionID { get; set; }
public int PatientID { get; set; }
public DateTime ExpectedDate { get; set; }
public int BedID { get; set; }
public string Phone { get; set; }
}
public PatientDBContext()
: base("PatientsDBContext")//connection string
{
}
public DbSet<Admission> Admission { get; set; }
public DbSet<Beds> Beds { get; set; }
public DbSet<Patient> Patient { get; set; }
}
view
#model IEnumerable<ChampPMS.Models.Patient>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create", null, new { #class = "btn btn-success" })
</p>
<table class="table table-condensed table-striped table-hover table-bordered ">
<tr>
<th>
#Html.DisplayNameFor(model => model.HouseChartNo)
</th>
<th>
#Html.DisplayNameFor(model => model.ClinicChartNo)
</th>
<th>
#Html.DisplayNameFor(model => model.Title)
</th>
<th>
#Html.DisplayNameFor(model => model.FirstName)
</th>
<th>
#Html.DisplayNameFor(model => model.DOB)
</th>
<th>
#Html.DisplayNameFor(model => model.Bed)----->from bed table
</th>
<th>
#Html.DisplayNameFor(model => model.ExpectedDate)----->from admission table
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.HouseChartNo)
</td>
<td>
#Html.DisplayFor(modelItem => item.ClinicChartNo)
</td>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.SurName)
</td>
<td>
#Html.DisplayFor(modelItem => item.DOB)
</td>
<td>
#Html.DisplayNameFor(model => model.Bed)------->from bed table
</td>
<td>
#Html.DisplayNameFor(model => model.ExpectedDate) ----->from admission table
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.PatientID }, new { #class = "btn btn-xs btn-info" }) |
#Html.ActionLink("Details", "Details", new { id = item.PatientID }, new { #class = "btn btn-xs btn-primary" }) |
#Html.ActionLink("Delete", "Delete", new { id = item.PatientID }, new { #class = "btn btn-xs btn-danger" })
</td>
</tr>
}
</table>
Controller
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using ChampPMS.Models;
namespace ChampPMS.Controllers
{
public class PatientsController : Controller
{
private PatientDBContext db = new PatientDBContext();
// GET: Patients
public ActionResult Index()
{
return View(db.Patient.ToList());
}
// GET: Patients/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Patient patient = db.Patient.Find(id);
if (patient == null)
{
return HttpNotFound();
}
return View(patient);
}
// GET: Patients/Create
public ActionResult Create()
{
return View();
}
// POST: Patients/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 ActionResult Create([Bind(Include = "PatientID,HouseChartNo,ClinicChartNo,Title,FirstName,SurName,DOB,HouseName,Street,Town,County,Telephone,Mobile,Gender,Occupation,Marital,TaxNumber,GMSnumber,DPSnumber,ReligionID,Status,HashCode")] Patient patient)
{
if (ModelState.IsValid)
{
db.Patient.Add(patient);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(patient);
}
// GET: Patients/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Patient patient = db.Patient.Find(id);
if (patient == null)
{
return HttpNotFound();
}
return View(patient);
}
// POST: Patients/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]
public ActionResult Edit([Bind(Include = "PatientID,HouseChartNo,ClinicChartNo,Title,FirstName,SurName,DOB,HouseName,Street,Town,County,Telephone,Mobile,Gender,Occupation,Marital,TaxNumber,GMSnumber,DPSnumber,ReligionID,Status,HashCode")] Patient patient)
{
if (ModelState.IsValid)
{
db.Entry(patient).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(patient);
}
// GET: Patients/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Patient patient = db.Patient.Find(id);
if (patient == null)
{
return HttpNotFound();
}
return View(patient);
}
// POST: Patients/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Patient patient = db.Patient.Find(id);
db.Patient.Remove(patient);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}

Rather than return the data directly from the database to the View you should create a View-Model in the controller action.
This ViewModel would contain all of the information that you need to display.
Using a ViewModel ensures that only the data required for the View is returned. It means rendering your View is more simple and you can use data from many different sources in one single ViewModel.

Related

Returning array or List of models from form in Razor View to action on Submit

I am working on a learning project in which I created a view which displays a list of Delisted Books( isActive = false) populated by calling an api.
The view has a list of books + a checkbox in front of each book so that upon clicking the books we want to set active and hit the save button, it returns the books which are selected to the action in controller.
This is the view I am working with :
#model IEnumerable<MvcBooksList.Models.Book>
#{
ViewData["Title"] = "Delisted Books";
}
#if (Model != null)
{
#using (Html.BeginForm("DelistedForm", "Book", FormMethod.Post, new { #id = "myForm" }))
{
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.BookName)
</th>
<th>
#Html.DisplayNameFor(model => model.Author)
</th>
<th>
#Html.DisplayNameFor(model => model.Publisher)
</th>
<th>
Enlist
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.BookName)
#Html.HiddenFor(modelItem => item.BookName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Author)
#Html.HiddenFor(modelItem => item.Author)
</td>
<td>
#Html.DisplayFor(modelItem => item.Publisher)
#Html.HiddenFor(modelItem => item.Publisher)
</td>
<td>
#Html.CheckBoxFor(modelItem => item.IsActive)
</td>
</tr>
}
</tbody>
</table>
<input type="submit" value="Save" /> <input type = "button" value = "Cancel" onclick = "location.href='#Url.Action("Index", "Home")'" />
}
}
else
{
<h3>No Books currently delisted</h3>
}
This is the model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MvcBooksList.Models
{
public class Book
{
public string BookName { get; set; }
public string Author { get; set; }
public string Category { get; set; }
public string Subcategory { get; set; }
public string Publisher { get; set; }
public bool IsActive { get; set; }
public double? Price { get; set; }
public int Pages { get; set; }
public string AddedBy { get; set; }
public string ModifiedBy { get; set; }
public DateTime AddedOn { get; set; }
public DateTime LastModifiedOn { get; set; }
}
}
and this is the controller:
[HttpPost]
public async Task<ActionResult> DelistedForm(IEnumerable<Book> fromDelist)
{
foreach (var item in fromDelist)
{
if (item.IsActive == true)
//CALL
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress = baseAddressOfBookApi;
var resopnse = await client.GetAsync("Book/EnlistBook?id="+item.BookName.ToString());
if (!resopnse.IsSuccessStatusCode)
{
return View(null);
}
}
}
}
return RedirectToAction("Index","Home");
}
Dont mind the code inside the action.
So when I press the submit button nothing gets passed to the action. The fromDelist collection is showing a count of 0.
So ,what am I doing wrong.
And Is it possible that I can return the names of books that are checked.
BookController ::
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using MvcBooksList.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
namespace MvcBooksList.Controllers
{
public class BookController : Controller
{
readonly Uri baseAddressOfBookApi;
public BookController(IConfiguration configuration)
{
baseAddressOfBookApi = new Uri(configuration.GetSection("ApiAddress:BookAPI").Value);
}
/*
public ActionResult Edit(string name)
{
return View(name); //repalce with the name of view
}
public ActionResult Delete(string name)
{
return View(name); //repalce with the name of view
}
public ActionResult Delist(string name)
{
return View(name); //repalce with the name of view
}
*/
public async Task<ActionResult> ViewDelistedBooks()
{
List<Book> bookdetails = new List<Book>();
using (HttpClient client = new HttpClient())
{
client.BaseAddress = baseAddressOfBookApi;
var response = await client.GetAsync("Book/ViewDelistedBooks");
if (response.IsSuccessStatusCode)
{
var BookResponse = response.Content.ReadAsStringAsync().Result;
bookdetails = JsonConvert.DeserializeObject<List<Book>>(BookResponse);
}
}
return View(bookdetails);
}
public ActionResult Cancel()
{
return View("~/Views/Home/Index.cshtml");
}
[HttpPost]
public async Task<ActionResult> DelistedForm(IEnumerable<Book> fromDelist)
{
foreach (var item in fromDelist)
{
if (item.IsActive == true)
//CALL
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress = baseAddressOfBookApi;
var resopnse = await client.GetAsync("Book/EnlistBook?id="+item.BookName.ToString());
if (!resopnse.IsSuccessStatusCode)
{
return View(null);
}
}
}
}
return RedirectToAction("Index","Home");
}
}
}
Try to replace foreach by for
#model List<MvcBooksList.Models.Book>
#for (int i = 0; i < Model.Count(); i+=1)
{
......
<td>
#Html.DisplayFor(model=> model[i].Publisher)
#Html.HiddenFor(model => model[i].Publisher)
</td>
<td>
#Html.CheckBoxFor(model => model[i].IsActive)
</td>
</tr>
.... and so on for all
and replace a table header
<th>
#Html.DisplayNameFor(model => model[0].BookName)
</th>
<th>
#Html.DisplayNameFor(model => model[0].Author)
</th>

Foreign Key property won't set correctly

I have made an earlier post with similar code, and have updated the models to use a helper class instead of a ViewBag. It seemed to work like a charm until the database was updated.
These are my model classes.
[Table("Store")]
public class Store
{
[Key]
public int StoreId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}
[Table("Purchase")]
public class Purchase
{
[Key]
public int Id { get; set; }
public int StoreId { get; set; }
[ForeignKey("StoreId")]
public Store Store { get; set; }
}
public class PurchaseDBContext : DbContext
{
public DbSet<Purchase> Purchases { get; set; }
public DbSet<Store> Stores { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
public class PurchaseCreateHelper
{
public Purchase Purchase { get; set; }
public List<Store> Stores { get; set; }
}
}
My relevant part of the View for this question:
<div class="form-group">
#Html.LabelFor(model => model.Purchase.StoreId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Purchase.StoreId, new SelectList(Model.Stores.Select( x => new { StoreId = x.StoreId, DisplayName = x.Name.ToString() + " - " + x.Address.ToString()}), "StoreId", "DisplayName"), new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Purchase.StoreId, "", new { #class = "text-danger" })
</div>
</div>
And the relevant part of my controller:
// GET: Purchases/Create
public ActionResult Create()
{
var purchaseHelper = new PurchaseCreateHelper()
{
Stores = db.Stores.ToList(),
Purchase = new Purchase()
};
return View(purchaseHelper);
}
// POST: Purchases/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Purchase purchase)
{
if (ModelState.IsValid)
{
db.Purchases.Add(purchase);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(purchase);
}
When my code comes to db.Purchases.Add(purchase) the Store property of the purchase object is set to null. The StoreId however seems to be perfectly fine. I don't get why the Store object won't change with the StoreId property as I have annotated it with [ForeignKey("StoreId")]. Where did I mess up the connection between StoreId and Store?
UPDATE #2
// GET: Purchases
public ActionResult Index()
{
return View(db.Purchases.ToList());
}
#model IEnumerable<BookKeeper.Models.Purchase>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Store.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Type)
</th>
<th>
#Html.DisplayNameFor(model => model.Price)
</th>
<th>
#Html.DisplayNameFor(model => model.Date)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => (item.Store.Name))
</td>
<td>
#Html.DisplayFor(modelItem => item.Type)
</td>
<td>
#Html.DisplayFor(modelItem => item.Price)
</td>
<td>
#Html.DisplayFor(modelItem => item.Date)
</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>
UPDATE #3
enter image description here
I assume that you don't see any value for the purchase.Store, that's because the model binder only bind the StoreId (when request is sent from Browser to Web Server) which you specified in
#Html.DropDownListFor(model => model.Purchase.StoreId, new SelectList(Model.Stores.Select( x => new { StoreId = x.StoreId, DisplayName = x.Name.ToString() + " - " + x.Address.ToString()}), "StoreId", "DisplayName"), new { #class = "form-control" })
The populating of purchase.Store belongs to EF. EF will load that Store when you do
dbContext.Purchases.Include(x => x.Store).FirstOrDefault(x => x.ID == 1234);
UPDATE:
If you want the Store object in POST action
// POST: Purchases/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Purchase purchase)
{
if (ModelState.IsValid)
{
db.Purchases.Add(purchase);
db.SaveChanges();
purchase = dbContext.Purchases.Include(x => x.Store).FirstOrDefault(x => x.ID == purchase.ID); // Not sure why you need Store information at this step.
return RedirectToAction("Index");
}
return View(purchase);
}

Invalid object name 'dbo.TableName' ASP

I looked everywhere and I can't figure out what the problem is with my asp project.
Basically I get this error
Invalid object name dbo.Enquires.
It's looking for a table which doesn't exist, and I never mention that table anywhere, not sure why it's looking for it.
EnquireController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data;
using System.Data.Entity;
using System.Net;
using PetePersonalTrainerFinal.Models;
namespace PetePersonalTrainerFinal.Controllers
{
public class EnquireController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
[Authorize(Roles ="Admin, Mod")]
// Enquire
public ActionResult Index(string SearchName)
{
var items = from i in db.Enquiries select i;
if (!String.IsNullOrEmpty(SearchName))
{
items = items.Where(i => i.Name.Contains(SearchName));
}
return View(items);
}
[Authorize(Roles ="Admin, Mod")]
// Details
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Enquire enquire = db.Enquiries.Find(id);
if (enquire == null)
{
return HttpNotFound();
}
return View(enquire);
}
// Create
public ActionResult Create()
{
return View();
}
// Post Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create ([Bind(Include ="Id,Name,Address,Suburb,State,Postcode,Email,Phone,Description")] Enquire enquire)
{
if (ModelState.IsValid)
{
db.Enquiries.Add(enquire);
db.SaveChanges();
TempData["message"] = "Your enquiry has been successufully submitted.";
return RedirectToAction("Index", "Home");
}
return View(enquire);
}
// Edit
[Authorize(Roles = "Admin")]
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Enquire enquire = db.Enquiries.Find(id);
if (enquire == null)
{
return HttpNotFound();
}
return View(enquire);
}
//Post edit
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = "Admin")]
public ActionResult Edit([Bind(Include = "Id,Name,Address,Suburb,State,Postcode,Email,Phone,Description")] Enquire enquire)
{
if (ModelState.IsValid)
{
db.Enquiries.Add(enquire);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(enquire);
}
// Delete
[Authorize(Roles = "Admin")]
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Enquire enquire = db.Enquiries.Find(id);
if (enquire == null)
{
return HttpNotFound();
}
return View(enquire);
}
// Post Delete
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
[Authorize(Roles = "Admin")]
public ActionResult DeleteConfirmed(int id)
{
Enquire enquire = db.Enquiries.Find(id);
db.Enquiries.Remove(enquire);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
Enquire.cs Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace PetePersonalTrainerFinal.Models
{
public class Enquire
{
public int Id { get; set; }
[Required(ErrorMessage = "Name is required")]
[Display(Name = "Name")]
public string Name { get; set; }
[Required(ErrorMessage = "Address is required")]
[Display(Name = "Address")]
public string Address { get; set; }
[Required(ErrorMessage = "Suburb is required")]
[Display(Name = "Suburb")]
public string Suburb { get; set; }
[Required(ErrorMessage = "State is required")]
[Display(Name = "State")]
public string State { get; set; }
[Required(ErrorMessage = "Postcode is required")]
[Display(Name = "Postcode")]
public string Postcode { get; set; }
[Required(ErrorMessage = "Email is required")]
[Display(Name = "Email")]
public string Email { get; set; }
[Required(ErrorMessage = "Phone is required")]
[Display(Name = "Phone")]
public string Phone { get; set; }
[Required(ErrorMessage = "Description is required")]
[Display(Name = "Description")]
public string Description { get; set; }
}
}
And that is The Page I get the error on.
#model IEnumerable<PetePersonalTrainerFinal.Models.Enquire>
#{
ViewBag.Title = "Index";
}
<div class="container">
<h2>Index</h2>
#if (User.IsInRole("Admin"))
{
<p>
#Html.ActionLink("Create New", "Create")
</p>
}
#if (User.IsInRole("Admin") || User.IsInRole("Mod"))
{
using (Html.BeginForm())
{
<p>
Name: #Html.TextBox("SearchName")
<input type="submit" value="Search" />
</p>
}
}
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Address)
</th>
<th>
#Html.DisplayNameFor(model => model.Suburb)
</th>
<th>
#Html.DisplayNameFor(model => model.State)
</th>
<th>
#Html.DisplayNameFor(model => model.Postcode)
</th>
<th>
#Html.DisplayNameFor(model => model.Email)
</th>
<th>
#Html.DisplayNameFor(model => model.Phone)
</th>
<th>
#Html.DisplayNameFor(model => model.Description)
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Address)
</td>
<td>
#Html.DisplayFor(modelItem => item.Suburb)
</td>
<td>
#Html.DisplayFor(modelItem => item.State)
</td>
<td>
#Html.DisplayFor(modelItem => item.Postcode)
</td>
<td>
#Html.DisplayFor(modelItem => item.Email)
</td>
<td>
#Html.DisplayFor(modelItem => item.Phone)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#Html.ActionLink("Update", "Edit", new { id = item.Id}) |
#Html.ActionLink("Details", "Details", new { id = item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id = item.Id })
</td>
</tr>
}
</table>
For some reason I keep getting the error and I can't seem to fix it. I don't have much experience with asp.net. Here is the error I get http://pastebin.com/Gmmhn0VX
It keeps looking for dbo.Enquires and that doesn't exist, I also searched the whole project and I can't see anywhere that something refers to dbo.Enquires.
Any help would be appreciated.
Edit: Here is the ApplicationDBContext
using System.Data.Entity;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
namespace PetePersonalTrainerFinal.Models
{
// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/? LinkID=317594 to learn more.
public class ApplicationUser : IdentityUser
{
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("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
public System.Data.Entity.DbSet<PetePersonalTrainerFinal.Models.Price> Prices { get; set; }
public System.Data.Entity.DbSet<PetePersonalTrainerFinal.Models.Enquire> Enquiries { get; set; }
}
}
Decorating Enquire Model class with [Table("Enquiries")] fixed the issue.
Credits to Ajinder Singh.

MVC create, edit, delete actions "Cannot implicitly convert type" error

I am going to create a delete button for my table
here is my code
<center>
<H2>LIST OF REGISTERED STUDENTS</H2>
<br /><br />
</center>
<table class="table">
<tr>
<th>
Name
</th>
<th>
Last Name
</th>
<th>
E-Mail
</th>
<th>
Password
</th>
<th>
Student Number
</th>
<th>
Program
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.student_name)
</td>
<td>
#Html.DisplayFor(modelItem => item.student_lname)
</td>
<td>
#Html.DisplayFor(modelItem => item.student_email)
</td>
<td>
#Html.DisplayFor(modelItem => item.student_password)
</td>
<td>
#Html.DisplayFor(modelItem => item.student_number)
</td>
<td>
#Html.DisplayFor(modelItem => item.student_program)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.student_name }) |
#Html.ActionLink("Details", "Details", new { id=item.student_name }) |
#Html.ActionLink("Delete", "Delete", new { id=item.student_name })
</td>
</tr>
}
</table>
but when I create the delete syntax
public ActionResult Delete(int id = 0)
{
CSdbConnectionString db = new CSdbConnectionString();
student student = db.students.Find(id);
if(student == null)
{
return HttpNotFound();
}
return View(student);
}
// POST: Student/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
CSdbConnectionString db = new CSdbConnectionString();
try
{
student student = db.students.Find(id);
db.students.Remove(student);
db.SaveChanges();
return RedirectToAction("ViewStudents","ConsulSked");
}
catch
{
return View();
}
}
the code db.students.Find(id) has an error of
Cannot implicitly convert type CS.Models.student to CS.student
here is my student class
[Table("student")]
public class student
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int student_id { get; set; }
public string student_name { get; set; }
public string student_lname { get; set; }
public string student_email { get; set; }
public string student_password { get; set; }
public string student_number { get; set; }
public string student_program { get; set; }
}
and this is my data context class
public class CSdbConnectionString : DbContext
{
public CSdbConnectionString()
: base("CSdbConnectionString")
{ }
public DbSet<appointment> appointments { get; set; }
public DbSet<faculty> faculties { get; set; }
public DbSet<sched> scheds { get; set; }
public DbSet<student> students { get; set; }
}
what should I do? I can't create the delete option.
I have found the solution, for those in the future who will have the same error.
It is because I have a .dbml file in my project so I can store my stored procedures. That is the
CS.student
the one in my namespace model is the
CS.Models.student
and that's the one we need.
So instead of
student student = db.students.Find(id);
make it
CS.Models.student student = db.students.Find(id);

Related data not showing asp.net c#

After reading this tutorial http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/reading-related-data-with-the-entity-framework-in-an-asp-net-mvc-application I have created some models, controllers and views.
The recipes are showing just fine in the view, but I can't get the RecipeLines to show.
RecipeModel
public class RecipeModel
{
[Key]
public int RecipeId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string ImageUrl { get; set; }
public virtual ICollection<RecipeLine> RecipeLines { get; set; }
}
RecipeLine
public class RecipeLine
{
[Key]
public int RecipeLineId { get; set; }
public int RecipeId { get; set; }
public double Quantity { get; set; }
public UnitOfMeasureModel UnitOfMeasure { get; set; }
public IngredientModel Ingredient { get; set; }
}
RecipeViewModel
public class RecipeViewModel
{
public IEnumerable<RecipeModel> RecipeModels { get; set; }
public IEnumerable<RecipeLine> RecipeLines { get; set; }
}
Recipecontroller
public class RecipeController : Controller
{
private RecipeApplicationDb db = new RecipeApplicationDb();
[HttpGet]
public ActionResult Index(int? id)
{
var viewModel = new RecipeViewModel();
viewModel.RecipeModels = db.Recipes
//.Include(i => i.Name)
.Include(i => i.RecipeLines);
if (id != null)
{
ViewBag.RecipeId = id.Value;
viewModel.RecipeLines = viewModel.RecipeModels.Where(i => i.RecipeId == id.Value).Single().RecipeLines;
}
return View(viewModel);
}
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
RecipeModel recipeModel = db.Recipes.Find(id);
if (recipeModel == null)
{
return HttpNotFound();
}
return View(recipeModel);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
And the view
#model RecipeApplication.Models.RecipeViewModel
#{
ViewBag.Title = "Recepten";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
Naam
</th>
<th>
Omschrijving
</th>
<th>
Afbeelding
</th>
</tr>
#foreach (var item in Model.RecipeModels) {
string selectedRow = "";
if(item.RecipeId == ViewBag.RecipeId)
{
selectedRow = "success";
}
<tr class="#selectedRow" valign="top">
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#if (item.ImageUrl != null)
{
#Html.DisplayFor(modelItem => item.ImageUrl)
}
</td>
<td>
#Html.ActionLink("Select", "Index", new { id = item.RecipeId}) |
#Html.ActionLink("Edit", "Edit", new { id=item.RecipeId }) |
#Html.ActionLink("Details", "Details", new { id=item.RecipeId }) |
#Html.ActionLink("Delete", "Delete", new { id=item.RecipeId })
</td>
</tr>
}
</table>
#if (Model.RecipeLines != null)
{
foreach (var item in Model.RecipeLines)
{
string selectedRow = "";
if (item.RecipeId == ViewBag.id)
{
<p>#item.Quantity #item.UnitOfMeasure #item.Ingredient</p>
}
}
}
When selecting the recipe, the line does get a proper color, and I see an id-value in the URL-string.
If someone could help with this one, that would be awesome.
You're comparing item.RecipeId to ViewBag.id, which doesn't exist. The ViewBag member you set in the controller action was ViewBag.RecipeId.
However, you don't need this conditional at all. All of the recipe lines are already for that recipe id, because you specifically set only those recipe items in Model.RecipeLines.
//change your controller action
[HttpGet]
public ActionResult Index(int? id)
{
if(id == null) return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
var model = new RecipeViewModel();
var data = db.RecipeModel.Include(i => i.RecipeLines)
.Where(x=>x.RecipeId == id)
.ToList();
model.RecipeModels = data;
return View(model);
}
//change your viewModel
public class RecipeViewModel
{
public IEnumerable<RecipeModel> RecipeModels { get; set; }
}
//this is in the view
#if (Model.RecipeLines != null)
{
foreach (var item in Model.RecipeModels.RecipeLines)
{
<p>
#item.Quantity
#item.UnitOfMeasure
#item.Ingredient
</p>
}
}

Categories

Resources