I am relatively new to MVC 5, and having a problem figuring out how to update a relational table. I am using EF code first. I've spent a lot of time searching for a solution but I just can't find anything that relates to my code which is why I have no other choise than to ask here, so I apologise up front if this has already been answered.
I am including the relational table in my Razor view which works very well. But when I want to update the table it simply doesn't update even though I get no errors with my current code.
I've also tried adding an extra Bind[(Include = "Id,FirstName,LastName")], but this used the Booking FirstName and LastName.
I am unsure if my methods are the "proper" ones. My logic tells me that I need to fetch the data from the view and retrieve them in the controller but I don't know how if I can't use Bind or the db.Entry(item).State = EntityState.Modified?
Booking.cs
namespace Ventures.Innovation.InteractiveModel.Context
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
public partial class Bookings
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Bookings()
{
AttendingPeople = new HashSet<AttendingPeople>();
}
public int Id { get; set; }
[Required]
[StringLength(128)]
public string AspNetUserFk { get; set; }
[Required]
public DateTime Date { get; set; }
[Required]
[StringLength(100)]
public string FirstName { get; set; }
[Required]
[StringLength(50)]
public string LastName { get; set; }
public virtual AspNetUsers AspNetUsers { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<AttendingPeople> AttendingPeople { get; set; }
}
}
AttendingPeople.cs
namespace Ventures.Innovation.InteractiveModel.Context
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
public partial class AttendingPeople
{
public int Id { get; set; }
public int BookingId { get; set; }
[Required]
[StringLength(100)]
public string FirstName { get; set; }
[Required]
[StringLength(50)]
public string LastName { get; set; }
public virtual Bookings Bookings { get; set; }
}
}
Controller
// GET: AdminHome/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Bookings bookings = db.Bookings.Find(id);
if (bookings == null)
{
return HttpNotFound();
}
ViewBag.AspNetUserFk = new SelectList(db.AspNetUsers, "Id", "Email", bookings.AspNetUserFk);
var attendingPeople = db.AttendingPeople.Where(a => a.BookingId == id).ToList();
bookings.AttendingPeople = attendingPeople;
return View(bookings);
}
// POST: AdminHome/Edit/5
// 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 Edit([Bind(Include = "Id,AspNetUserFk,Date,FirstName,LastName")] Bookings bookings)
{
if (ModelState.IsValid)
{
db.Entry(bookings).State = EntityState.Modified;
db.SaveChanges();
var editedAttendingPeople = db.AttendingPeople.Where(a => a.BookingId == bookings.Id).ToList();
foreach (var item in editedAttendingPeople)
{
db.Entry(item).State = EntityState.Modified;
}
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.AspNetUserFk = new SelectList(db.AspNetUsers, "Id", "Email", bookings.AspNetUserFk);
return View(bookings);
}
View
#model Ventures.Innovation.InteractiveModel.Context.Bookings
#{
ViewBag.Title = "Edit booking";
}
<h2>Edit booking</h2>
<hr />
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Id)
</div>
<div class="form-group">
#Html.LabelFor(model => model.AspNetUserFk, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("AspNetUserFk", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.AspNetUserFk, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Date, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Date, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Date, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FirstName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.FirstName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LastName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LastName, "", new { #class = "text-danger" })
</div>
</div>
#if (Model.AttendingPeople.Count > 0)
{
#Html.Label("Attending people")
foreach (var attendingPeople in Model.AttendingPeople)
{
<div class="form-group">
<div class="col-md-10">
#Html.LabelFor(modelItem => attendingPeople.FirstName, htmlAttributes: new { #class = "control-label col-md-5", #style = "padding-left: 0;" })
#Html.LabelFor(modelItem => attendingPeople.LastName, htmlAttributes: new { #class = "control-label col-md-5", #style = "padding-left: 0;" })
</div>
<div class="col-md-10">
#Html.EditorFor(modelItem => attendingPeople.FirstName, new { htmlAttributes = new { #class = "form-control col-md-5", #style = "display: initial;" } })
#Html.EditorFor(modelItem => attendingPeople.LastName, new { htmlAttributes = new { #class = "form-control col-md-5", #style = "display: initial;" } })
</div>
</div>
}
}
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save changes" class="btn btn-primary" />
</div>
</div>
</div>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
I want to save the updated data to AttendingPeople table in the database but nothing happens.
Thanks to JARRRRG for helping me out here. :)
To solve this I needed to make sure my naming was exactly the same. Apparently this is how it finds/binds from the view to the controller. Also I needed to make sure I used a for loop so the collection could distinguish between the objects.
So this is my updated view:
#if (Model.AttendingPeople.Count > 0)
{
#Html.Label("Attending people")
var attendingPeople = Model.AttendingPeople.ToArray();
foreach (int i = 0; i < attendingPeople.Length; i++)
{
#Html.HiddenFor(modelItem => attendingPeople[i].Id)
<div class="form-group">
<div class="col-md-10">
#Html.LabelFor(modelItem => attendingPeople[i].FirstName, htmlAttributes: new { #class = "control-label col-md-5", #style = "padding-left: 0;" })
#Html.LabelFor(modelItem => attendingPeople[i].LastName, htmlAttributes: new { #class = "control-label col-md-5", #style = "padding-left: 0;" })
</div>
<div class="col-md-10">
#Html.EditorFor(modelItem => attendingPeople[i].FirstName, new { htmlAttributes = new { #class = "form-control col-md-5", #style = "display: initial;" } })
#Html.EditorFor(modelItem => attendingPeople[i].LastName, new { htmlAttributes = new { #class = "form-control col-md-5", #style = "display: initial;" } })
</div>
</div>
}
}
And this is my new Edit:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,AspNetUserFk,Date,FirstName,LastName")] Bookings bookings, ICollection<AttendingPeople> attendingPeople)
{
if (ModelState.IsValid)
{
db.Entry(bookings).State = EntityState.Modified;
db.SaveChanges();
foreach (var item in attendingPeople)
{
item.BookingId = bookings.Id;
db.Entry(item).State = EntityState.Modified;
}
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.AspNetUserFk = new SelectList(db.AspNetUsers, "Id", "Email", bookings.AspNetUserFk);
bookings = db.Bookings.Include(at => at.AttendingPeople).SingleOrDefault(b => b.Id == bookings.Id)
return View(bookings);
}
I have this working for one view and have replicated it exactly for two others - however the new ones will not work...
The view creates the file structure, uploads the file and records 2 entries in the DB Relating to the file upload all other fields in the view save information - the FileDesc and FileName fields return blank.
I must be missing something really obvious...
Model:
namespace inventIT.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Web;
public partial class EquipmentReceipt
{
public int RecordID { get; set; }
[Required]
[Display(Name = "Staff Member")]
public string AssessorID { get; set; }
[Required]
[Display(Name = "Equipment Type")]
public string EquipmentType { get; set; }
[Display(Name = "Serial Number (Where Required)")]
public string EquipmentSerial { get; set; }
[Display(Name = "Computer AD Name / IMEI Number")]
public string ADIMEI { get; set; }
[Required]
[Display(Name = "Added By")]
public string ITAssignedBy { get; set; }
[Required]
[Display(Name = "Date Assigned")]
public Nullable<System.DateTime> DateAssigned { get; set; }
[Display(Name = "Date Withdrawn")]
public Nullable<System.DateTime> DateWithdrawn { get; set; }
[Display(Name = "Notes")]
public string Notes { get; set; }
[Display(Name = "File Attachment")]
public string FileDesc { get; set; }
[Display(Name = "File Attachment")]
public string FileName { get; set; }
public string Extension { get; set; }
[DisplayFormat(DataFormatString = "{0:dd-mm-yyyy}")]
public DateTime Date1 { get; set; }
public Nullable<int> FileID { get; set; }
public string CreateFolder { get; set; }
public virtual ADIMEILookup ADIMEILookup { get; set; }
public virtual Lookup Lookup { get; set; }
public virtual ITTeamLookup ITTeamLookup { get; set; }
public virtual StaffMemberLookup StaffMemberLookup { get; set; }
}
}
Controller:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using inventIT.Models;
namespace inventIT.Controllers
{
public class EquipmentReceiptsController : Controller
{
private HAWKTRAINING_INVENTITEntities db = new HAWKTRAINING_INVENTITEntities();
// GET: EquipmentReceipts
public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page, int? PageSize)
{
ViewBag.searchString = "";
ViewBag.CurrentSort = sortOrder;
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
ViewBag.CurrentFilter = searchString;
var AssessorIDs = from s in db.EquipmentReceipts
select s;
if (!String.IsNullOrEmpty(searchString))
{
AssessorIDs = AssessorIDs.Where(s => s.AssessorID.Contains(searchString) || searchString == null || searchString == "");
}
switch (sortOrder)
{
case "name_desc":
AssessorIDs = AssessorIDs.OrderByDescending(s => s.AssessorID);
break;
case "Date":
AssessorIDs = AssessorIDs.OrderBy(s => s.DateAssigned);
break;
case "date_desc":
AssessorIDs = AssessorIDs.OrderByDescending(s => s.DateAssigned);
break;
default: // Name ascending
AssessorIDs = AssessorIDs.OrderBy(s => s.AssessorID);
break;
}
var equipmentReceipts = db.EquipmentReceipts.Include(e => e.ADIMEILookup).Include(e => e.Lookup).Include(e => e.ITTeamLookup).Include(e => e.StaffMemberLookup);
return View(db.EquipmentReceipts.Where(s => s.AssessorID.Contains(searchString) || searchString == null || searchString == "").OrderByDescending(c => c.AssessorID).ToList());
}
// GET: EquipmentReceipts/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
EquipmentReceipt equipmentReceipt = db.EquipmentReceipts.Find(id);
if (equipmentReceipt == null)
{
return HttpNotFound();
}
return View(equipmentReceipt);
}
// GET: EquipmentReceipts/Create
public ActionResult Create()
{
ViewBag.ADIMEI = new SelectList(db.ADIMEILookups, "ADIMEIID", "ADIMEI");
ViewBag.EquipmentType = new SelectList(db.Lookups.Where(c => c.Fieldname == "EquipmentType"), "KeyID", "Title");
ViewBag.ITAssignedBy = new SelectList(db.ITTeamLookups, "ITTeamID", "ITTeam");
ViewBag.AssessorID = new SelectList(db.StaffMemberLookups, "StaffMemberID", "StaffMember");
return View();
}
// POST: EquipmentReceipts/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([Bind(Include = "RecordID,AssessorID,EquipmentType,EquipmentSerial,ADIMEI,ITAssignedBy,DateAssigned,DateWithdrawn,Notes,ComputerModel,FileDesc")] EquipmentReceipt equipmentReceipt)
{
// POST: File Upload Script Starts
if (ModelState.IsValid)
{
List<EquipmentReceipt> fileDetails = new List<EquipmentReceipt>();
for (int i = 0; i < Request.Files.Count; i++)
{
var file = Request.Files[i];
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
EquipmentReceipt fileDetail = new EquipmentReceipt()
{
FileName = fileName,
Extension = Path.GetExtension(fileName)
};
fileDetails.Add(fileDetail);
var Date = DateTime.Now;
var Date2 = Date.ToString("dd-MM-yyyy");
var Date3 = Date.ToString("HHmmss");
string pathToCreate = Path.Combine("~/App_Data/uploads/Equipment_Receipts", Date2, Date3);
bool exists = System.IO.Directory.Exists(Server.MapPath(pathToCreate));
if (!exists)
System.IO.Directory.CreateDirectory(Server.MapPath(pathToCreate));
var path2 = Path.Combine(Server.MapPath(pathToCreate), Date3 + "_" + fileDetail.FileName);
equipmentReceipt.FileDesc = path2;
equipmentReceipt.FileName = Date3 + "_" + fileDetail.FileName;
System.IO.Directory.Exists(pathToCreate);
file.SaveAs(equipmentReceipt.FileDesc);
}
}
db.EquipmentReceipts.Add(equipmentReceipt);
db.SaveChanges();
return RedirectToAction("Index");
}
if (ModelState.IsValid)
{
try
{
db.EquipmentReceipts.Add(equipmentReceipt);
db.SaveChanges();
return RedirectToAction("Index");
}
catch (Exception ex)
{
return View("Error", new HandleErrorInfo(ex, "EquipmentReceipt", "Create"));
}
}
// POST: File Upload Script Ends
ViewBag.ADIMEI = new SelectList(db.ADIMEILookups, "ADIMEIID", "ADIMEI");
ViewBag.EquipmentType = new SelectList(db.Lookups.Where(c => c.Fieldname == "EquipmentList"), "KeyID", "Title");
ViewBag.ITAssignedBy = new SelectList(db.ITTeamLookups, "ITTeamID", "ITTeam");
ViewBag.AssessorID = new SelectList(db.StaffMemberLookups, "StaffMemberID", "StaffMember");
return View(equipmentReceipt);
}
// GET: EquipmentReceipts/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
EquipmentReceipt equipmentReceipt = db.EquipmentReceipts.Find(id);
if (equipmentReceipt == null)
{
return HttpNotFound();
}
ViewBag.ADIMEI = new SelectList(db.ADIMEILookups, "ADIMEIID", "ADIMEI");
ViewBag.EquipmentType = new SelectList(db.Lookups.Where(c => c.Fieldname == "EquipmentList"), "KeyID", "Title");
ViewBag.ITAssignedBy = new SelectList(db.ITTeamLookups, "ITTeamID", "ITTeam");
ViewBag.AssessorID = new SelectList(db.StaffMemberLookups, "StaffMemberID", "StaffMember");
return View(equipmentReceipt);
}
// GET: EquipmentReceipts/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
EquipmentReceipt equipmentReceipt = db.EquipmentReceipts.Find(id);
if (equipmentReceipt == null)
{
return HttpNotFound();
}
return View(equipmentReceipt);
}
// POST: EquipmentReceipts/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
EquipmentReceipt equipmentReceipt = db.EquipmentReceipts.Find(id);
db.EquipmentReceipts.Remove(equipmentReceipt);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
View
#model inventIT.Models.EquipmentReceipt
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Equipment Receipts</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Create</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.AssessorID, "Staff Member", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("AssessorID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.AssessorID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.EquipmentType, "Equipment Type", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("EquipmentType", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.EquipmentType, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ADIMEI, "Computer AD Name/IMEI", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ADIMEI", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ADIMEI, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.EquipmentSerial, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.EquipmentSerial, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.EquipmentSerial, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.DateAssigned, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.DateAssigned, new { htmlAttributes = new { #class = "form-control jqueryui-marker-datepicker" } })
#Html.ValidationMessageFor(model => model.DateAssigned, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.DateWithdrawn, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.DateWithdrawn, new { htmlAttributes = new { #class = "form-control jqueryui-marker-datepicker" } })
#Html.ValidationMessageFor(model => model.DateWithdrawn, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Notes, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Notes, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Notes, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ITAssignedBy, "ITAssignedBy", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ITAssignedBy", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ITAssignedBy, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FileDesc, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.HiddenFor(x => x.FileDesc)
<input type="file" name="file3" id="file" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Please add in your form tag, new {enctype = "multipart/form-data"}
#using (Html.BeginForm("Create", "EquipmentReceipts", FormMethod.Post, new {enctype = "multipart/form-data" }))
ORIGINAL
I have a website where I can manage cars, brands, and car models. Right now I have controllers, models and views, the application is working, everything was auto generated by Visual Studio, and i am using entity framework (database first).
When I try to create a car, the dropdowns with brands and Car models are not cascading like I want.
I have a solution: add a class (or other property/attribute) to each option tag on each select (dropdown). Then, with JS, i'll do the rest. I just want to know how can I do a foreach loop to build my dropdown, even if it's not the best solution, i'm not discussing that. Remember, I need to do a foreach loop to the carmodel Model, inside the Cars View.
EDIT
Car View
#model MyApp.Models.car
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>car</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.bodytypeId, "bodytypeId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("bodytypeId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.bodytypeId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.manufacturerId, "manufacturerId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("manufacturerId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.manufacturerId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.modelId, "modelId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("modelId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.modelId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.versionId, "versionId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("versionId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.versionId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.fuelId, "fuelId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("fuelId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.fuelId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.transmissionId, "transmissionId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("transmissionId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.transmissionId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.colorId, "colorId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("colorId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.colorId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.horsePower, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.horsePower, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.horsePower, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.kw, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.kw, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.kw, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.cc, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.cc, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.cc, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Co2Emissions, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Co2Emissions, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Co2Emissions, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.mileage, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.mileage, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.mileage, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.year, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.year, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.year, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.doors, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.doors, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.doors, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.seats, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.seats, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.seats, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.plate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.plate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.plate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.price, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.price, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.price, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.shortDescription, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.shortDescription, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.shortDescription, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.longDescription, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.longDescription, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.longDescription, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.sold, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.sold)
#Html.ValidationMessageFor(model => model.sold, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.active, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.active)
#Html.ValidationMessageFor(model => model.active, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.dateAdded, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.dateAdded, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.dateAdded, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.dateSold, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.dateSold, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.dateSold, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Car Model
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace MyApp.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
public partial class car
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public car()
{
this.carimages = new HashSet<carimage>();
}
public int id { get; set; }
[Display(Name = "#")]
public Nullable<int> bodytypeId { get; set; }
[Display(Name = "Body Type")]
public Nullable<int> manufacturerId { get; set; }
[Display(Name = "Model")]
public Nullable<int> modelId { get; set; }
[Display(Name = "Version")]
public Nullable<int> versionId { get; set; }
[Display(Name = "Fuel")]
public Nullable<int> fuelId { get; set; }
[Display(Name = "Transmission")]
public Nullable<int> transmissionId { get; set; }
[Display(Name = "Color")]
public Nullable<int> colorId { get; set; }
[Display(Name = "HP")]
public Nullable<int> horsePower { get; set; }
[Display(Name = "KW")]
public Nullable<int> kw { get; set; }
[Display(Name = "CC")]
public Nullable<int> cc { get; set; }
[Display(Name = "CO2")]
public Nullable<double> Co2Emissions { get; set; }
[Display(Name = "Mileage")]
public Nullable<int> mileage { get; set; }
[Display(Name = "Year")]
public Nullable<int> year { get; set; }
[Display(Name = "Doors")]
public Nullable<int> doors { get; set; }
[Display(Name = "Seats")]
public Nullable<int> seats { get; set; }
[Display(Name = "Plate")]
public string plate { get; set; }
[Display(Name = "Price")]
public Nullable<int> price { get; set; }
[Display(Name = "Short Description")]
public string shortDescription { get; set; }
[Display(Name = "Long Description")]
public string longDescription { get; set; }
[Display(Name = "Sold")]
public bool sold { get; set; }
[Display(Name = "Active")]
public bool active { get; set; }
[Display(Name = "Date Added")]
[DataType(DataType.DateTime)]
[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy hh:mm}", ApplyFormatInEditMode = true)]
public Nullable<System.DateTime> dateAdded { get; set; }
[Display(Name = "Date Sold")]
[DataType(DataType.DateTime)]
[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy hh:mm}", ApplyFormatInEditMode = true)]
public Nullable<System.DateTime> dateSold { get; set; }
public virtual bodytype bodytype { get; set; }
public virtual color color { get; set; }
public virtual fuel fuel { get; set; }
public virtual manufacturer manufacturer { get; set; }
public virtual model model { get; set; }
public virtual transmission transmission { get; set; }
public virtual version version { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<carimage> carimages { get; set; }
}
}
Car 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 MyApp.Models;
namespace MyApp.Controllers
{
public class carsController : Controller
{
private MyAppEntities db = new MyAppEntities();
// GET: cars
public ActionResult Index(string id)
{
string searchString = id;
var cars = db.cars.Include(c => c.bodytype).Include(c => c.color).Include(c => c.fuel).Include(c => c.manufacturer).Include(c => c.model).Include(c => c.transmission).Include(c => c.version);
if (!String.IsNullOrEmpty(searchString))
{
cars = cars.Where(s => s.bodytype.name.Contains(searchString) ||
s.cc.ToString().Contains(searchString) ||
s.Co2Emissions.ToString().Contains(searchString) ||
s.color.name.Contains(searchString) ||
s.dateAdded.Value.ToString("dd-mm-yyyy").Contains(searchString) ||
s.dateSold.Value.ToString("dd-mm-yyyy").Contains(searchString) ||
s.doors.ToString().Contains(searchString) ||
s.fuel.name.Contains(searchString) ||
s.horsePower.ToString().Contains(searchString) ||
s.id.ToString().Contains(searchString) ||
s.kw.ToString().Contains(searchString) ||
s.longDescription.Contains(searchString) ||
s.manufacturer.name.Contains(searchString) ||
s.mileage.ToString().Contains(searchString) ||
s.model.name.Contains(searchString) ||
s.plate.Contains(searchString) ||
s.price.ToString().Contains(searchString) ||
s.seats.ToString().Contains(searchString) ||
s.shortDescription.Contains(searchString) ||
s.transmission.name.Contains(searchString) ||
s.version.name.Contains(searchString) ||
s.year.ToString().Contains(searchString)
);
}
return View(cars.ToList());
}
// GET: cars/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
car car = db.cars.Find(id);
if (car == null)
{
return HttpNotFound();
}
return View(car);
}
// GET: cars/Create
public ActionResult Create()
{
ViewBag.bodytypeId = new SelectList(db.bodytypes, "id", "name");
ViewBag.colorId = new SelectList(db.colors, "id", "name");
ViewBag.fuelId = new SelectList(db.fuels, "id", "name");
ViewBag.manufacturerId = new SelectList(db.manufacturers, "id", "name");
ViewBag.modelId = new SelectList(db.models, "id", "name");
ViewBag.transmissionId = new SelectList(db.transmissions, "id", "name");
ViewBag.versionId = new SelectList(db.versions, "id", "name");
return View();
}
// POST: cars/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 = "id,bodytypeId,manufacturerId,modelId,versionId,fuelId,transmissionId,colorId,horsePower,kw,cc,Co2Emissions,mileage,year,doors,seats,plate,price,shortDescription,longDescription,sold,active,dateAdded,dateSold")] car car)
{
if (ModelState.IsValid)
{
db.cars.Add(car);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.bodytypeId = new SelectList(db.bodytypes, "id", "name", car.bodytypeId);
ViewBag.colorId = new SelectList(db.colors, "id", "name", car.colorId);
ViewBag.fuelId = new SelectList(db.fuels, "id", "name", car.fuelId);
ViewBag.manufacturerId = new SelectList(db.manufacturers, "id", "name", car.manufacturerId);
ViewBag.modelId = new SelectList(db.models, "id", "name", car.modelId);
ViewBag.transmissionId = new SelectList(db.transmissions, "id", "name", car.transmissionId);
ViewBag.versionId = new SelectList(db.versions, "id", "name", car.versionId);
return View(car);
}
// GET: cars/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
car car = db.cars.Find(id);
if (car == null)
{
return HttpNotFound();
}
ViewBag.bodytypeId = new SelectList(db.bodytypes, "id", "name", car.bodytypeId);
ViewBag.colorId = new SelectList(db.colors, "id", "name", car.colorId);
ViewBag.fuelId = new SelectList(db.fuels, "id", "name", car.fuelId);
ViewBag.manufacturerId = new SelectList(db.manufacturers, "id", "name", car.manufacturerId);
ViewBag.modelId = new SelectList(db.models, "id", "name", car.modelId);
ViewBag.transmissionId = new SelectList(db.transmissions, "id", "name", car.transmissionId);
ViewBag.versionId = new SelectList(db.versions, "id", "name", car.versionId);
return View(car);
}
// POST: cars/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 = "id,bodytypeId,manufacturerId,modelId,versionId,fuelId,transmissionId,colorId,horsePower,kw,cc,Co2Emissions,mileage,year,doors,seats,plate,price,shortDescription,longDescription,sold,active,dateAdded,dateSold")] car car)
{
if (ModelState.IsValid)
{
db.Entry(car).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.bodytypeId = new SelectList(db.bodytypes, "id", "name", car.bodytypeId);
ViewBag.colorId = new SelectList(db.colors, "id", "name", car.colorId);
ViewBag.fuelId = new SelectList(db.fuels, "id", "name", car.fuelId);
ViewBag.manufacturerId = new SelectList(db.manufacturers, "id", "name", car.manufacturerId);
ViewBag.modelId = new SelectList(db.models, "id", "name", car.modelId);
ViewBag.transmissionId = new SelectList(db.transmissions, "id", "name", car.transmissionId);
ViewBag.versionId = new SelectList(db.versions, "id", "name", car.versionId);
return View(car);
}
// GET: cars/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
car car = db.cars.Find(id);
if (car == null)
{
return HttpNotFound();
}
return View(car);
}
// POST: cars/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
car car = db.cars.Find(id);
db.cars.Remove(car);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
Original
With ASP.NET MVC, you use server-side pre-processing to bind servers-side models to the .cshtml. From within the markup you can use tag helpers to build out common controls and user input components, this is where the razor view engine comes into play. Odeto-Code by Scott Allen has a great article on how you use these technologies together to build out a drop-down-list control specifically.
Here is part of that examples, .cshtml:
#Html.LabelFor(m=>m.SelectedFlavorId)
#Html.DropDownListFor(m => m.SelectedFlavorId, Model.FlavorItems)
#Html.ValidationMessageFor(m=>m.SelectedFlavorId)
<input type="submit" value="Submit" />
And here is the corresponding model, ViewModel.cs:
public class ViewModel
{
private readonly List<IceCreamFlavor> _flavors;
[Display(Name = "Favorite Flavor")]
public int SelectedFlavorId { get; set; }
public IEnumerable<SelectListItem> FlavorItems
{
get { return new SelectList(_flavors, "Id", "Name");}
}
}
As an additional resource there is actually several other stackoverflow Q/A's that cover questions similar to this, here is one that is noteable.
Update 1
I just want to know how can I do a foreach loop to build my dropdown
Again you can use the razor view engine here. It allows for interaction with a server-side C# model and a means to build HTML markup from that. Here is an example:
<select>
#{
foreach (var item in Model.ListOfItems)
{
<option value="item.Value" customAttribute="item.SomethingSpecial">
item.Name
</option>
}
}
</select>
Update 2
You car model does not define a list of models. You need to specify what the options are in order to do a foreach. In other words you cannot build a dropdownlist from a property on a C# model that is not a list. Does that help?
You can do this in C# rather than JS, a quick example here:
public class FindUser
{
// Where the items from the DB will be kept
public Dictionary<int, string> CountryList { get; set; }
// Used to store the users selected option
public int SelectedCountry { get; set; }
// A constructor to be called when the page renders
public FindUser()
{
PopulateCountryDropdown();
}
public void PopulateLeaDropdown()
{
// 1. Grab your items from the database, store it within a databale
// 2. Loop through the datatable and add each row to the list
CountryList = new Dictionary<int, string>();
foreach(DataRow row in dt.Rows)
{
CountryList.Add(Convert.ToInt32(row["ID"]), row["country"].ToString());
}
}
}
Then in your frontend add:
#Html.DropDownListFor(u => u.SelectedCountry, new SelectList(Model.CountryList, "Key", "Value"), "Select your country", new { #class = "form-control countries", id = "country_list" })
Solution found HERE
School database with the following 2 tables.
StateMaster
DistrictMaster
Step 1
Open Visual Studio then select File >> New >> Project then select ASP.Net MVC 4 Web Application.
Step 2
Select Internet Application then click OK.
Step 3
Select the Model folder then create a new Model class.
StudentModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcDemoApplication.Models
{
public class StudentModel
{
public IList<SelectListItem> StateNames { get; set; }
public IList<SelectListItem> DistrictNames { get; set; }
}
}
Step 4
Create a .edmx file and connect with the database.
Step 5
Create a new Controller. In this article I create DropDownListController.cs.
DropDownListController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcDemoApplication.Models;
namespace MvcDemoApplication.Controllers
{
public class DropDownListController : Controller
{
//
// GET: /DropDownList/
SchoolEntities schoolEntity = new SchoolEntities();
public ActionResult Index()
{
List<SelectListItem> stateNames = new List<SelectListItem>();
StudentModel stuModel=new StudentModel();
List<StateMaster> states = schoolEntity.StateMasters.ToList();
states.ForEach(x =>
{
stateNames.Add(new SelectListItem { Text = x.StateName , Value = x.StateId.ToString() });
});
stuModel.StateNames = stateNames;
return View(stuModel);
}
}
}
Index.cshtml
#model MvcDemoApplication.Models.StudentModel
#{
ViewBag.Title = "Index";
}
<script src="~/Scripts/jquery-1.7.1.min.js"></script>
<h2>Cascading Dropdownlist</h2>
<table>
<tr>
<td>
<label>State</label>
</td>
<td>
#Html.DropDownListFor(x => x.StateNames, Model.StateNames, "--Select--", new { #id="ddlState"});
</td>
</tr>
</table>
Understand the Code
In Studentmodel we have the following 2 properties:
public IList<SelectListItem> StateNames { get; set; }
public IList<SelectListItem> DistrictNames { get; set; }
Here we are using the SelectListItem class, this class has the following 3 properties:
Selected: This is a bool type to show in a dropdown (as selected) true or false by default.
Text: This is a string type, for the dropdown text.
Value: This is string type for the value of the dropdown
If you notice in the dropdownlist, we also need the same properties. For this reason we are using SelectListItem in a Ilist.
DropdownlistController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcDemoApplication.Models;
namespace MvcDemoApplication.Controllers
{
public class DropDownListController : Controller
{
//
// GET: /DropDownList/
SchoolEntities schoolEntity = new SchoolEntities();
public ActionResult Index()
{
List<SelectListItem> stateNames = new List<SelectListItem>();
StudentModel stuModel=new StudentModel();
List<StateMaster> states = schoolEntity.StateMasters.ToList();
states.ForEach(x =>
{
stateNames.Add(new SelectListItem { Text = x.StateName , Value = x.StateId.ToString() });
});
stuModel.StateNames = stateNames;
return View(stuModel);
}
}
In the preceding code we create the SchoolEntities object, in this object all the related tables exist.
SchoolEntities schoolEntity = new SchoolEntities();
List<StateMaster> states = schoolEntity.StateMasters.ToList();
In the preceding line of code, all the related data of the StateMasters tables comes into the StateMaster list object.
states.ForEach(x =>
{
stateNames.Add(new SelectListItem { Text = x.StateName , Value = x.StateId.ToString() });
});
Now it is time to add entity data into the Text and value properties, the all collection will be stored into the stateNames object.
Index.cshtml
#model MvcDemoApplication.Models.StudentModel
#{
ViewBag.Title = "Index";
}
<script src="~/Scripts/jquery-1.7.1.min.js"></script>
<h2>Cascading Dropdownlist</h2>
<table>
<tr>
<td>
<label>State</label>
</td>
<td>
#Html.DropDownListFor(x => x.StateNames, Model.StateNames, "--Select--", new { #id="ddlState"});
</td>
</tr>
</table>
The preceding code shows the model data in View. Now to understand how it works.
#Html.DropDownListFor(x => x.StateNames, Model.StateNames, "--Select--", new { #id="ddlState"});
Look at the preceding code, we used here, #Html helper classes for creating a DropDownList. In the DropDownListFor helper class we used 4 parameters.
x=>x.StateNames: For getting the values of the collection from the entity.
Model.StateNames: Collections of states.
“—Select--”: Default value, when the dropdown list will be populated.
new {#id=”ddlState”}: In this part we can define an id, class and name for the control.
How to do cascading between two dropdownlists.
DropdownlistController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcDemoApplication.Models;
namespace MvcDemoApplication.Controllers
{
public class DropDownListController : Controller
{
//
// GET: /DropDownList/
SchoolEntities1 schoolEntity = new SchoolEntities1();
public ActionResult Index()
{
List<SelectListItem> stateNames = new List<SelectListItem>();
StudentModel stuModel=new StudentModel();
List<StateMaster> states = schoolEntity.StateMasters.ToList();
states.ForEach(x =>
{
stateNames.Add(new SelectListItem { Text = x.StateName , Value = x.StateId.ToString() });
});
stuModel.StateNames = stateNames;
return View(stuModel);
}
[HttpPost]
public ActionResult GetDistrict(string stateId)
{
int statId;
List<SelectListItem> districtNames = new List<SelectListItem>();
if (!string.IsNullOrEmpty(stateId))
{
statId = Convert.ToInt32(stateId);
List<DistrictMaster> districts = schoolEntity.DistrictMasters.Where(x => x.StateId == statId).ToList();
districts.ForEach(x =>
{
districtNames.Add(new SelectListItem { Text = x.DistrictName, Value = x.DistrictId.ToString() });
});
}
return Json(districtNames, JsonRequestBehavior.AllowGet);
}
}
}
Index.cshtml
#model MvcDemoApplication.Models.StudentModel
#{
ViewBag.Title = "Index";
}
<script src="~/Scripts/jquery-1.7.1.min.js"></script>
<h2>Cascading Dropdownlist</h2>
<table>
<tr>
<td>
<label>State</label>
</td>
<td>
#Html.DropDownListFor(x => x.StateNames, Model.StateNames, "--Select--", new { #id="ddlState"});
</td>
</tr>
<tr>
<td>
<label>District</label>
</td>
<td id="District">
#Html.DropDownListFor(x => x.DistrictNames, new List<SelectListItem>(), "--Select--", new { #id="ddlDistrict"});
</td>
</tr>
</table>
<script type="text/javascript">
$(document).ready(function () {
$('#ddlState').change(function () {
$.ajax({
type: "post",
url: "/DropDownList/GetDistrict",
data: { stateId: $('#ddlState').val() },
datatype: "json",
traditional: true,
success: function (data) {
var district = "<select id='ddlDistrict'>";
district = district + '<option value="">--Select--</option>';
for (var i = 0; i < data.length; i++)
{
district = district + '<option value=' + data[i].Value + '>' + data[i].Text + '</option>';
}
district = district + '</select>';
$('#District').html(district);
}
});
});
});
</script>
That's it. Press F5 and run your code.
Look at Nuget package Mvc.CascadeDropDown:
https://www.nuget.org/packages/Mvc.CascadeDropDown/
Here is how I am using it:
#Html.CascadingDropDownListFor(m => m.ArticleGroup_Nr, "Department_Nr",
Url.Action("GetArticleGroups"), "DepartmentNr", "-- Select item --", true,
new { #class = "form-control", style = "width: 450px" })
Here Department_Nr specifies the parent dropdown elsewhere in the View - either a regular dropdownlist or another cascaded dropdownlist.
I then created a JSON Action GetArticleGroups on the same Controller that accepts a DepartmentNr parameter, which is passed the current value of the parent dropdown.
The JSON Action will be called everytime the value of the parent dropdown is changed because #Html.Cascading... also attaches an onchange-eventhandler to the parent object.
public virtual JsonResult GetArticleGroups(int DepartmentNr)
{
var items = provider.ArticleGroups.Where(m => m.Parent_Nr == DepartmentNr);
return GetJson(items); // convert items to JSON [ { "Value":"xx", "Text":"yy" } ]
}
private JsonResult GetJson(IQueryable<ICatalogueItem> items)
{
var data = items
.Select(x => new { Value = x.Number, Text = x.Text })
.OrderBy(o => o.Text);
return Json(data, JsonRequestBehavior.AllowGet);
}
... Or see this article on how to build it yourself:
http://www.c-sharpcorner.com/UploadFile/4d9083/creating-simple-cascading-dropdownlist-in-mvc-4-using-razor/
I have the following error staring me in the face.
The model item passed into the dictionary is of type 'System.Data.Entity.DynamicProxies.game_04BC2EA428E3397C72CED2755A5A78B93F676BBC970F6B9A8635AD53B08FEBCB', but this dictionary requires a model item of type 'TeamBuildingCompetition.ViewModels.EditGameVM'
I have an ASP.NET NVC 5 intranet application. I created an edit view from a view model to update contents of my database. Content of the database in question is an html content which was posted in by a rich text editor. When I load the edit view, it shows the above error.
Below is my edit view:
#model TeamBuildingCompetition.ViewModels.EditGameVM
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout_new.cshtml";
}
<script>
tinymce.init({ selector: '#description' });
tinymce.init({ selector: '#gameRule' });
</script>
#using (Html.BeginForm("Update", "Game", FormMethod.Post))
{
#Html.AntiForgeryToken()
<section id="middle">
<div class="container">
<div class="form-horizontal">
<div class="center"><h1>Edit Games </h1></div>
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.gameID)
<div class="form-group">
#Html.LabelFor(model => model.gameName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-8">
#Html.EditorFor(model => model.gameName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.gameName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.description, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-8">
#Html.EditorFor(model => model.description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.description, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.gameRule, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-8">
#Html.EditorFor(model => model.gameRule, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.gameRule, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.gamePicture, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-8">
#Html.TextBoxFor(model => model.gamePicture, new { #type = "file", #name = "gamePicture" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
</div>
</section>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Below is the View Model for the Edit View:
namespace TeamBuildingCompetition.ViewModels
{
public class EditGameVM
{
public int gameID { get; set; }
[Required]
[Display(Name = "Game Name")]
public string gameName { get; set; }
[Required][AllowHtml]
[Display(Name = "Description")]
public string description { get; set; }
[Required]
[AllowHtml]
[Display(Name = "Game Rules")]
public string gameRule { get; set; }
[Display(Name = "Game Picture")]
public string gamePicture { get; set; }
}
}
And finally, here's the controller to do the update:
public ActionResult Update(EditGameVM model)
{
try {
game objGame = new game
{
gameID = model.gameID,
gameName = model.gameName,
description = model.description,
gameRule = model.gameRule,
gamePicture = model.gamePicture.ToString()
};
objBs.gameBs.Update(objGame);
TempData["Msg"] = "Created Successfully!";
return RedirectToAction("Edit");
}
catch (DbEntityValidationException dbEx)
{
var sb = new StringBuilder();
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
sb.AppendLine(string.Format("Entity:'{0}' Property: '{1}' Error: '{2}'",
validationErrors.Entry.Entity.GetType().FullName,
validationError.PropertyName,
validationError.ErrorMessage));
}
}
//throw new Exception(string.Format("Failed saving data: '{0}'", sb.ToString()), dbEx);
TempData["Msg"] = sb.ToString();
return RedirectToAction("Edit");
}
}
Here's my Get Method:
public ActionResult Edit(int id = 0)
{
if (id == 0)
{
id = 1;
}
var gameList = objBs.gameBs.GetByID(id);
return View(gameList);
}
I will appreciate all effort to resolving this.
You do not send your model to view, so you caught an error. It is possible to do by this way:
As you use some temporary storage mechanisom like TempData
TempData["Msg"] = objGame;
return RedirectToAction("Edit");
Then just read it in your GET Action method again of your View.
public ActionResult Edit()
{
//Here you should cast your TempData to EditGameVM:
EditGameVM receivedModel=TempData["Msg"] as EditGameVM;
//To take data from TempData["Msg"], you should use receivedModel object:
string gameID=receivedModel.gameID;
string gameName=receivedModel.gameName;
return View(receivedModel);
}
TempData uses Session object behind the scene to store the data. But once the data is read the data is terminated.
I failed to pass the model to my view hence, the above error. After careful examination of my code, I did the following according to https://stackoverflow.com/users/3559349/stephen-muecke advice. All credit goes to this great guy.
public ActionResult Edit(int id = 0)
{
if (id == 0)
{
id = 1;
}
var gameList = objBs.gameBs.GetByID(id);
EditGameVM model = new EditGameVM
{
gameID = id,
gameName = gameList.gameName,
gamePicture = gameList.gamePicture,
gameRule = gameList.gameRule,
description = gameList.description
};
return View(model);
}