Getting type instead of value - c#

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")

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")

How can I pass list of strongly type objects from controller to a dropdown on a view?

I would like to pass list of strongly typed object to a dropdown which is located on my view.
Usually to achieve this I used ViewBags like in following example:
public ActionResult ChooseLevel()
{
List<Levels> LevelList = GetAllLevels();
ViewBag.LevelList = LevelList
var model = new Levels();
return View(model);
}
And I would simply write this on a view, and I would get all my levels listed there:
<div class="form-group">
#Html.LabelFor(model => model.LevelId, new { #class = "control-label col-md-3 col-sm-3" })
<div class="col-md-9 col-sm-9">
#Html.DropDownListFor(model => model.LevelId, new SelectList(ViewBag.LevelList, "LevelId", "LevelName"), "", new { #class = "form-control" })
</div>
</div>
But now I'm wondering can I simply pass my list of Levels there, and choose them from dropdown list, without storing them to a viewbag first?
For example :
public ActionResult ChooseLevel()
{
List<Levels> LevelList = GetAllLevels();
return View(LevelList);
}
On a view I would accept multiple items by writing IEnumerable on a view:
#model IEnumerable<Levels>
and after that I could somehow choose only one item and post it back to a server?
How can I solve that issue?
You need to add this List to your existing Model or View Model:
class ModelName
{
public virtual IEnumerable<SelectListItem> lstTypes { get; set; }
public virtual int intTypeId { get; set; }
//Other existing properties here
}
On your Controller, you can now add this list to your Model before you return to your view:
ModelName objModel = new ModelName();
List<Levels> LevelList = GetAllLevels();
objModel.lstTypes = LevelList.Select(y => new SelectListItem()
{
Value = y.LevelId.ToString(),
Text = y.LevelName.ToString()
});
return View(objModel);
Then you can now display it on your view:
#model ModelName
//First parameter will be the Id that will be selected by your user when they post it
//Second parameter will be the enumerable list of dropdown
//Third parameter is the default option which is optional, and the last is the HTML attributes
#Html.DropDownListFor(c => c.intTypeId, Model.lstTypes , "Please select an item", new { #class = "form-control" })
You can create new viewmodel that contains multiple models (old model and LevelList model). like this:
public class newViewModel
{
public IEnumerable<level> levels{ get; set;}
public OldModel oldModel {get; set;}
}
Model class
public class TestViewModel
{
public List<SelectListItem> EnterpriseList { get; set; }
}
Controller:
var model = new TestViewModel() {
EnterpriseList = EnterpriseData.Select(p=>new SelectListItem() { Value = p.Value,Text = p.Name}).ToList()
};
return View(model);
View:
#Html.DropDownListFor(p => p.Enterprise, Model.EnterpriseList, "Please select a", new { #class = "form-control", #style = "height: auto" })

Adding drop down list to mvc page [duplicate]

This question already has answers here:
The ViewData item that has the key 'XXX' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'
(6 answers)
Closed 6 years ago.
This is giving me a hard time to implement. I've generated a controller and view to handle updating a model.
However in the Create.cshtml I need to add a drop down with database users (using db.Users.Tolist()) to populate the dropdown.
<div class="form-group">
#Html.LabelFor(model => model.UserId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
// #Html.EditorFor(model => model.UserId, new { htmlAttributes = new { #class = "form-control" } })
#Html.DropDownListFor(model => model.UserId, ViewData["u"] as IEnumerable<SelectListItem>)
</div>
</div>
So I've taken #Html.EditorFor() and replaced it with #Html.DropDownListFor() to show the dropdown list. And this does work but I get an error when I click submit.
The ViewData item that has the key 'UserId' is of type 'System.String' but must be of type 'IEnumerable'.
Here's the Model.
public class pdf
{
[Key]
public int ID { get; set; }
public string UserId { get; set; }
public Guid FileGuid { get; set; }
public string FileName { get; set; }
public string FileLocation { get; set; }
}
And the Create controller.
public ActionResult Create()
{
if (ModelState.IsValid)
{
var u = db.Users.Select(x => new { UserId = x.Id, UserName = x.UserName }).ToList();
//u[0].UserName
ViewBag.userinfo = new System.Web.Mvc.MultiSelectList(u, "UserId", "UserName");
IEnumerable<SelectListItem> u1 = new SelectList(db.Users.ToList(), "Id", "UserName");
ViewData["u"] = u1;
}
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID,UserId,FileGuid,FileName,FileLocation")] pdf pdf)
{
if (ModelState.IsValid)
{
db.tblPDF.Add(pdf);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(pdf);
}
I feel that I'm almost there. But just need a push in the right direction to make this work.
This is how you can make your SelectListItems
ViewData["items"] = db.UserProfiles
.Select(x => new SelectListItem() { Text = x.UserName, Value = x.UserId.ToString() });
This is how you would use it
#Html.DropDownListFor(model => model.UserId, ViewData["items"] as IEnumerable<SelectListItem>)
I've never tried passing a selectlistitem collection directly to the page. I typically add the list to the model and then create a new selectlistitem collection with razor.
Do you have the choice to modify your model?
#Html.DropDownListFor(model => model.UserId, Model.availableUsers.Select(user => new SelectListItem() { Text = user.displayVariable, Value = user.userId, Selected = user.userId == model.UserId }).ToArray())

How to bind database with dropdownlist in MVC5?

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
});

Populating a Dropdownlistfor with multiple ids

I am using a dropdownlistfor html helper to pick ingredients in a dish. I can get it to display all the ingredients, i can make it post the value's, but i cant seem to populate it when i want to edit a dish with existing ingredients.
My controller:
public ActionResult Edit(int id)
{
DishViewModel dvm = new DishViewModel();
dvm.Dish = facade.GetDishGateway().Get(id);
dvm.Dish.Ingredients.ForEach(x => dvm.SelectedIds.Add(x.Id));
return View(dvm);
}
My viewmodel:
public class DishViewModel
{
Facade facade = new Facade();
public DishViewModel()
{
SelectedList = facade.GetIngredientGateway().GetAll().FirstOrDefault().Id.ToString();
SelectedIds = new List<int>();
}
public Dish Dish { get; set; }
public List<int> SelectedIds { get; set; }
public string SelectedList { get; set; }
public List<SelectListItem> SelectList
{
get
{
List<SelectListItem> temp = new List<SelectListItem>();
foreach (var item in facade.GetIngredientGateway().GetAll())
{
temp.Add(new SelectListItem { Text = item.Name + ": " + item.Price + ",-", Value = item.Id.ToString() });
}
return temp;
}
}
}
My View:
<div class="form-group row">
#Html.LabelFor(model => model.Dish.Ingredients, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.SelectedIds, Model.SelectList, new { #multiple = "multiple"})
</div>
</div>
By my understanding, the model => model.selectedIds is the one populating the dropdownlistfor, but it does not seem to work
Html.DropDownListFor renders a standard select element, where only one option may be marked as selected.
If you want a select multiple, then you should use Html.ListBoxFor.

Categories

Resources