How to bind database with dropdownlist in MVC5? - c#

I tried to bind the database with dropdown using IEnumerable. But it showing error which is showed in the below image.
My Model (CustomerViewModel)
public Nullable<System.Guid> AreaID { get; set; }
public string Area { get; set; }
public IEnumerable<SelectListItem> AreaList { get; set; }
My Controller
public ActionResult Create ()
{
CustomerViewModel cvm = new CustomerViewModel();
cvm.AreaList = db.Areas.Where(a => a.IsDeleted == false).Select(a => new SelectListItem()
{
Value = a.AreaID.ToString(),
Text = a.DisplayName
});
return View();
}
My View Code
#Html.LabelFor(model => model.Area, new { #class = "control-label" })
#Html.DropDownListFor(m => m.AreaID, Model.AreaList, "Please select a Area", new { #class = "form-control" })

The code you have works ok. The problem is that you are creating a query where you use the .ToString() method, which cannot be translated to a DB equivalent syntax.
To make it work, you need to select the items from DB using .ToList(), and after that create the SelectListItem
cvm.AreaList = db.Areas.Where(a => a.IsDeleted == false).ToList().Select(a => new SelectListItem()
{
Value = a.AreaID.ToString(),
Text = a.DisplayName
});

Related

Unable to provide input for a selected attribute of a drop down list in MVC

public partial class Department
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Department()
{
this.Employees = new HashSet<Employee>();
}
public int ID { get; set; }
public string Name { get; set; }
public Nullable<bool> IsSelected { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Employee> Employees { get; set; }
}
public ActionResult Create()
{
List<SelectListItem> DeptList = new List<SelectListItem>();
foreach (Department tempdept in db.Departments)
{
SelectListItem sli = new SelectListItem
{
Text = tempdept.Name,
Value = tempdept.ID.ToString(),
Selected = tempdept.IsSelected.HasValue ? tempdept.IsSelected.Value : false
};
DeptList.Add(sli);
}
ViewBag.Departments = DeptList;
return View();
}
<div class="form-group">
#Html.LabelFor(model => model.DepartmentID, "DepartmentID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.DepartmentID,(IEnumerable<SelectListItem>)ViewBag.Departments,new { #class = "form-control" ,
#selected = ViewBag.Departments.Selected.HasValue && ViewBag.Departments.Selected.Value ? "selected" : null
})
#Html.ValidationMessageFor(model => model.DepartmentID, "", new { #class = "text-danger" })
</div>
</div>
Above, I have mentioned the code for the model, the controller and then the view.
Basically, I was trying to set a default DropDownList Element by taking user input from the database using the IsSelected field in the Department table.
So if the IsSelected Column in the Database for the corresponding department has a 1 and all the others have a NULL or a 0, then the department that has a 1 gets selected as the default element in the DropDownList when there is a Get.
But as soon as I run my code I am encountered with the error
(''System.Collections.Generic.List' does not contain a definition for 'Selected'')
Unable to figure out such behavior.
Thanks in Advance!!!
Remove ur #selected = html attribute in the #Html.DropDownListFor, the drop down is smart enough to set the selected from the SelectListItem
In my case i filled the viewBag with strings so i create the collection of SelectListItem in #Razer but can also be filled from the controller
this is working for me:
in the xxx.cshtml file
#{
var weights = new List<SelectListItem>();
foreach (var item in ViewBag.PossibleWeights)
{
weights.Add(
new SelectListItem
{
Text = item,
Value = item,
Selected = item == Model.WeightCode
});
}
}
#Html.DropDownListFor(model => model.WeightCode, weights, new { #class = "form-control")

Getting type instead of value

Trying to create a dropdownbox. I want to populate the list with values, but instead I get types in it.
ViewModel
public class AdminViewModel
{
...
public IEnumerable<SelectListItem> Roles { get; set; }
}
Controller
[HttpGet]
public ActionResult AddAdmin()
{
DataAccessLayer.DoloContext col = new DataAccessLayer.DoloContext();
List<Roles> list = new List<Roles>(col.Roles.ToList());
AdminViewModel viewMod = new AdminViewModel();
viewMod.Roles = new SelectList(list);
return View(viewMod);
}
View
<div class="form-group">
#Html.LabelFor(model => model.Roles, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Roles, (SelectList) Model.Roles, "RoleName", "Choose")
</div>
</div>
What I get in my dropdownlist is AuthSys.Models.Roles
What am I doing wrong?
I have tried compare to the examples I can find here, but in the end, I keep getting the types.
Try populating your IEnumerable<SelectListItem> as the following:
viewMod.Roles = col.Roles
.ToList()
.Select(x => new SelectListItem()
{
Value = x.Value,
Text = x.Text
}).ToList();
With x.Value and x.Text being your desired properties of Role.
Assumed that you have Roles class in data source like this:
public class Roles
{
public int RoleId { get; set; }
public string RoleName { get; set; }
}
If you want to get selected value from IEnumerable<SelectListItem>, do the following steps:
1) Create additional property which will hold selected value in viewmodel.
public class AdminViewModel
{
public int SelectedRoleId { get; set; }
public IEnumerable<SelectListItem> Roles { get; set; }
}
2) Bind the option list into IEnumerable<SelectListItem> property like this:
public ActionResult AddAdmin()
{
DataAccessLayer.DoloContext col = new DataAccessLayer.DoloContext();
var viewMod = new AdminViewModel();
List<Roles> list = col.Roles.ToList();
viewMod.Roles = list.Select(x => new SelectListItem {
Text = x.RoleName,
Value = x.RoleId
}).ToList();
return View(viewMod);
}
3) Finally, bind selected value property and option list to DropDownListFor helper, also no need to convert Roles option list into SelectList because Roles already has type of IEnumerable<SelectListItem>:
#Html.DropDownListFor(model => model.SelectedRoleId, Model.Roles, "Choose")

Trying to get a dropdown working in asp.net core

I am trying to get a dropdown working in asp.net core but it doesnt even appear to like the first list that its supposed to populate staff memebers with. I have a table called activity header with a foreignkey field staff id linked to a staff table.
First here is the code I am trying from this tutorial
public IEnumerable<SelectListItem> GetStaff()
{
List <SelectListItem> staff = _db.Staff.AsNoTracking();
List <SelectListItem> selectListItems = _db.Staff.AsNoTracking()
.OrderBy(n => n.FirstName)
.Select(n =>
new SelectListItem
{
Value = n.StaffID.ToString(),
Text = n.FirstName.ToString() + " " + n.LastName.ToString()
}).ToList();
var stafftip = new SelectListItem()
{
Value = null,
Text = "--- select staff memeber---"
};
staff.Insert(0, stafftip );
return new SelectList(staff, "Value", "Text");
}
My Class for activity header
public class ActivityHeader
{
// other fields removed for brevity
[Required]
[Display(Name = "Staff")]
public int StaffId { get; set; }
public IEnumerable<Staff> Staff { get; set; }
}
My staff class here which should link to the other table with the staff id
public class Staff
{
[Key]
public int StaffID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int DepartmentId { get; set; }
public string StaffNumber { get; set; }
public virtual IEnumerable<Staff> Staff { get; set; }
}
This is my html for my view which is inside a bootstrap popup.
<div class="col-sm-3">
<label for="inputPostalCode">SOP</label>
<div class="form-group">
#Html.LabelFor(x => Model.Staff, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-5">
#Html.DropDownListFor(x => Model.StaffId, new SelectList(Model.Staff, "Value", "Text"), htmlAttributes: new { #class = "form-control", id = "Country" })
#Html.ValidationMessageFor(x => x.StaffId, "", new { #class = "text-danger" })
</div>
</div>
</div>
What i expect to see is a html drop down with the results from staff but linked to activity head with staff id.
But it doesn't appear to like this list for some reason. Exact error is
I see there are few mistakes in your DropDownList implementation:
Number #1 :
If you want if no item is selected from DropDownList then null value for the select list will be passed then don't need to set DropDownList level text as follows:
var stafftip = new SelectListItem()
{
Value = null,
Text = "--- select staff memeber---"
};
staff.Insert(0, stafftip );
Rather simply your GetStaff() method as follows:
public SelectList GetStaff()
{
var staffList = _db.Staff.Select(s => new
{
Value = s.StaffID,
Text = s.FirstName + " " + s.LastName
}).ToList();
return new SelectList(staffList, "Value", "Text");
}
Now in your model classes, replace public virtual IEnumerable<Staff> Staff { get; set; } with public SelectList Staff { get; set; }
Then in the view:
#Html.DropDownListFor(x => Model.StaffId, Model.Staff,"Select Staff", htmlAttributes: new { #class = "form-control", id = "Country" })
Number #2:
If you want, if no item is selected from DropDownList then default (0 or anything) value for the select list will be passed then write your GetStaff() method as follows:
public IEnumerable<SelectListItem> GetStaff()
{
List<SelectListItem> staffSelectListItems = _db.Staff.OrderBy(n => n.FirstName)
.Select(n => new SelectListItem
{
Value = n.StaffID.ToString(),
Text = n.FirstName.ToString() + " " + n.LastName.ToString()
}).ToList();
var defaultSelection = new SelectListItem()
{
Value = "0",
Text = "Select Staff Member",
Selected = true // <-- this is obligatory
};
staffSelectListItems.Insert(0, defaultSelection);
return staffSelectListItems;
}
Then in the view:
#Html.DropDownListFor(x => Model.StaffId,(List<SelectListItem>)Model.Staff, htmlAttributes: new { #class = "form-control", id = "Country" })
Hope it will now work for you!
public IEnumerable<SelectListItem> GetStaff()
{
List <SelectListItem> selectListItems = _db.Staff.AsNoTracking()
.OrderBy(n => n.FirstName)
.Select(n =>
new SelectListItem
{
Value = n.StaffID.ToString(),
Text = n.FirstName.ToString() + " " + n.LastName.ToString()
}).ToList();
var stafftip = new SelectListItem()
{
Value = null,
Text = "--- select staff memeber---"
};
selectListItems.Insert(0, stafftip );
return new SelectList(selectListItems, "Value", "Text");
}
You were trying to assign an IQueryable to a List which wasn't going to work. I have removed that line and fixed your use of the selectlist as staff is not needed.

Get value from DropDownList

I have simple site
controller.cs
public ActionResult Dodaj()
{
EduSiatkiEntities daneProgramu = new EduSiatkiEntities();
SelectList profileHasel = new SelectList(daneProgramu.SYS_PROFILE_HASEL.Select(e => new{ Value = e.idProfiluHasla, Text = e.nazwaProfilu,}), "Value", "Text");
ViewBag.profileHasel = profileHasel;
ViewBag.CzyZapisanoDane = "nie";
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Dodaj(Models.UzytkowniDodajkViewModel uzytkownikForm)
{
Debug.WriteLine(uzytkownikForm.idProfilHasla.Where(x => x.Selected=true).FirstOrDefault().Value.ToString());
if (ModelState.IsValid)
{
/**/
}
else
{
ViewBag.CzyZapisanoDane = "nie";
}
return View(uzytkownikForm);
}
view.cshtml
#Html.DropDownListFor(a => a.idProfilHasla, (SelectList)#ViewBag.profileHasel, "Wybierz opcje...", new { #class = "form-control" })
model.cs
[Display(Name = "Profil hasła użytkownika")]
[Required(ErrorMessage = "Wybierz profil hasła użytkownika")]
public IEnumerable<SelectListItem> idProfilHasla { get; set; }
When i debug the program I alway get NULL value from DropDownList (from code below)
Debug.WriteLine(uzytkownikForm.idProfilHasla.Where(x => x.Selected=true).FirstOrDefault().Value.ToString());
#Html.DropDownListFor(a => a.idProfilHasla, (SelectList)#ViewBag.profileHasel,
"Wybierz opcje...", new { #class = "form-control" })
For above DropDownList , idProfilHasla should be string type, because DropDownList selected value is a string.
[Display(Name = "Profil hasła użytkownika")]
[Required(ErrorMessage = "Wybierz profil hasła użytkownika")]
public string idProfilHasla { get; set; }
If you want to place SelectList inside model instead of ViewBag, you might want to read this answer.

asp.net mvc 5 dropdownlist not showing item in list just after adding it

What I'm trying to do...
I am trying to get a newly added item to display in a cascading dropdownlist.
Overview...
The first dropdownlist (I'll call it ddlCategory) is for selecting a Category of electrical devices (ie. Appliances, Audio-Visual, Lighting, etc.). The second dropdownlist (I'll call ddlElecDev) is populated with the devices which are filtered by the selected Category. If the device isn't listed in ddlElecDev then the user can click a link to add a new one. After saving the newly added electrical device, the user is redirected back to the original page with the electrical device id as a parameter.
All the above seems to work fine. However, when the user is redirected to the first page, not only is the newly added electrical device not selected in ddlElecDev, but it doesn't even appear in the list. Strangely, if I refresh the page, it is automatically selected.
Can anyone explain to me how to get the newly added device to be selected without having to refresh the page?
Here's the markup for selecting the category and electrical device:
<div class="form-group">
#Html.LabelFor(model => model.SelectedCategory, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.SelectedCategory, Model.Categories, "Select a Category", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.SelectedCategory, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ElectricalDeviceID, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.CascadingDropDownListFor(
expression: model => model.ElectricalDeviceID,
triggeredByProperty: model => model.SelectedCategory,
url: Url.Action("GetElectricalDevices", "ElectricalDeviceConfigurations"),
ajaxActionParamName: "categoryId",
optionLabel: "Select an Electrical Device",
disabledWhenParrentNotSelected: false,
htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ElectricalDeviceID, "", new { #class = "text-danger" })
#Html.ActionLink("Not Listed? Add a new Electrical Device", "AddNew", "ElectricalDevices", new { returnUrl = string.Format("/ElectricalDeviceConfigurations/AddConfiguration?eventVendorId={0}", Model.EventVendorID) }, null)
</div>
</div>
The documentation for the Cascading DropDownList Helper can be found at
https://github.com/alexanderar/Mvc.CascadeDropDown
Here's the Controller method for selecting the Electrical Device:
public ActionResult AddConfiguration(int? eventVendorId, int? newElecDev)
{
(Some code removed for brevity)
var selectedCategoryId = db.ElectricalDeviceCategoryLookups.Where(cat => cat.Category == Enums.ElectricalDeviceCategory.All).FirstOrDefault().ID;
var electricalDeviceID = (newElecDev.HasValue) ? newElecDev : null;
return View(new ElecDevConfigSelectionViewModel { EventVendorID = eventVendorId, EventVendor = eventVendor, Categories = GetCategories(), SelectedCategory = selectedCategoryId, ElectricalDeviceID = electricalDeviceID });
}
Here's the controller methods for populating the Categories and the Electrical Devices:
private List<SelectListItem> GetCategories()
{
var categories = new List<SelectListItem>();
db.ElectricalDeviceCategoryLookups.OrderBy(c => c.Description).ToList().ForEach(item => categories.Add(new SelectListItem { Text = item.Description, Value = item.ID.ToString() } ));
return categories;
}
public ActionResult GetElectricalDevices(int? categoryId)
{
if (categoryId.HasValue)
{
var selCategory = db.ElectricalDeviceCategoryLookups.Where(cat => cat.ID == categoryId).FirstOrDefault().Category;
var elecDevicesSelectList = new List<SelectListItem>();
var elecDevices = (selCategory == Enums.ElectricalDeviceCategory.All) ? db.ElectricalDevices.OrderBy(ed => ed.Name).ToList() : db.ElectricalDevices.Where(ed => ed.Category == selCategory).OrderBy(ed => ed.Name).ToList();
elecDevices.ForEach(ed => elecDevicesSelectList.Add(new SelectListItem { Text = ed.Name, Value = ed.ID.ToString() }));
return Json(elecDevicesSelectList, JsonRequestBehavior.AllowGet);
}
return null;
}
Here's the View Model:
public class ElecDevConfigSelectionViewModel
{
public int? EventVendorID { get; set; }
public EventVendor EventVendor { get; set; }
[Display(Name = "Category")]
public int SelectedCategory { get; set; }
public IList<SelectListItem> Categories { get; set; }
[Display(Name = "Electrical Device")]
public int? ElectricalDeviceID { get; set; }
}
Here's the controller methods for adding a new electrical device:
// GET: ElectricalDevices/AddNew
public ActionResult AddNew(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
var selectedCategoryId = db.ElectricalDeviceCategoryLookups.FirstOrDefault().ID;
return View(new AddNewElectricalDeviceViewModel { ReturnUrl = returnUrl, Categories = GetCategories(), SelectedCategory = null });
}
// POST: ElectricalDevices/AddNew
// 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 AddNew(AddNewElectricalDeviceViewModel model)
{
if (ModelState.IsValid)
{
var selectedCategory = db.ElectricalDeviceCategoryLookups.Find(model.SelectedCategory);
var electricalDevice = new ElectricalDevice
{
Name = model.ElectricalDevice.Name,
Description = model.ElectricalDevice.Description,
Category = selectedCategory.Category,
Wattage = model.ElectricalDevice.Wattage
};
db.ElectricalDevices.Add(electricalDevice);
db.SaveChanges();
var returnUrl = string.Format("{0}&newElecDev={1}", model.ReturnUrl, electricalDevice.ID);
return RedirectToLocal(returnUrl);
}
return View();
}
Here's the View Model for adding a new electrical device:
public class AddNewElectricalDeviceViewModel
{
public string ReturnUrl { get; set; }
[Display(Name = "Category")]
public int? SelectedCategory { get; set; }
public IList<SelectListItem> Categories { get; set; }
public ElectricalDevice ElectricalDevice { get; set; }
}

Categories

Resources