I feel this should be simple but haven't found a guide on here that explains the use of dropdownlistfor in MVC.
I have a simple List of Names in a method in a class Users:
public List<string> getUsersFullNames()
{
return (from da in db.Dat_Account
join ra in db.Ref_Account on da.AccountID equals ra.AccountID
select ra.FirstName + " " + ra.Surname).ToList();
}
I want to display each of these names in a dropdownlist so that a name can be selected.
I tried to get this working but have had no success.
My controller:
[Authorize]
public ActionResult ManageUserAccounts()
{
ViewBag.UserList = oUsers.getUsersFullNames();
return View();
}
My Model:
public class ManageUserAccountsViewModel
{
[Display(Name = "Users")]
public List<SelectListItem> UserList { get; set; }
}
My View:
Html.DropDownListFor(model => model.UserList, new SelectList(oUsers.getUsersFullNames(), "Select User"));
I'm quite new to asp.net MVC as I have always used webforms in the past. Has anyone any idea if this is possible or a way to display this?
Thanks,
I would recommend using the model directly in the view, instead of the ViewBag. Update your action to include a model reference:
public ActionResult ManageUserAccounts()
{
var model = new ManageUserAccountsViewModel();
model.UserList = oUsers.getUsersFullNames();
return View(model);
}
Your model should be updated to include a selected User property:
public class ManageUserAccountsViewModel
{
public string User { get; set; }
[Display(Name = "Users")]
public List<string> UserList { get; set; }
}
Your view should be binding to the model:
#model ManageUserAccountsViewModel
#Html.DropDownListFor(m => m.User, new SelectList(Model.UserList), "Select User")
Related
Ok, I'm trying to do a proper dropdown in Core 3.1. In this example https://learn.microsoft.com/en-us/aspnet/core/mvc/views/working-with-forms?view=aspnetcore-3.1#the-select-tag-helper
Model has a new list with hardcoded values
public string Country { get; set; }
public List<SelectListItem> Countries { get; } = new List<SelectListItem>
{
new SelectListItem { Value = "MX", Text = "Mexico" },
new SelectListItem { Value = "CA", Text = "Canada" },
new SelectListItem { Value = "US", Text = "USA" },
};
I looked for examples where the list is coming from the database but they are very inconsistent. The only way I was able to do the dropdown list is with the ViewBag which is not advised.
I have two models. 1.
public partial class Glossary
{
public int UniqueId { get; set; }
public int Category { get; set; }
public string DisplayText { get; set; }
}
which is my view model
public partial class AdminUser
{
[Key]
public int Id { get; set; }
public string UserName { get; set; }
public string UserLocation { get; set; }
public string UserStatus { get; set; }
//public IEnumerable<Glossary> Glossary { get; set; } //I used this for ViewBag
public List<SelectListItem> UserLocations { get; } = new List<SelectListItem>
{
according to the example my query should go here
};
}
Here is my controller:
public IActionResult Create()
{
// This is the ViewBag that worked with HTML helpers, but I'm trying to use tag-helpers.
/*IEnumerable<SelectListItem> LocationsList = _context.Glossary.Where(x => x.Category == 1).Select(x => new SelectListItem
{
Value = x.UniqueId.ToString(),
Text = x.DisplayText
});
ViewBag.LocationsList = LocationsList;
*/
return View();
}
All examples that found were hardcoded lists and nothing with getting it from the database. What is the proper way to get the data from the Glossary table through the view model with ViewBag? Any pointers are appreciated.
ALSO:
When using this example: Select Tag Helper in ASP.NET Core MVC
When I used
public SelectList Employees { set; get; }
I got error: InvalidOperationException: The entity type 'SelectListGroup' requires a primary key to be defined. If you intended to use a keyless entity type call 'HasNoKey()'.
Both of my tables have PK and adding [Key] to Glossary model didn't fix it.
If you'd like to retrieve data from db and populate a dropdown with retrieved data through a view model (or ViewBag), you can refer to following code snippet.
In AdminUser view model class, include these properties
public string Selected_Glossary { get; set; }
public List<SelectListItem> Glossary_List { get; set; }
In controller
public IActionResult Create(AdminUser model)
{
var adminuser_model = new AdminUser
{
UserName="test"
//for other properties
};
//retrieve data from Glossary table
var items = _context.Glossary.Where(x => x.Category == 1).Select(x => new SelectListItem
{
Value = x.UniqueId.ToString(),
Text = x.DisplayText
}).ToList();
//pass dropdown items through a view model
adminuser_model.Glossary_List = items;
////pass dropdown items through ViewBag
//ViewBag.Glossary_List = items;
return View(adminuser_model);
}
In view page
#model AdminUser
#{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<form asp-controller="Home" asp-action="Create" method="post">
<select asp-for="Selected_Glossary" asp-items="Model.Glossary_List"></select>
#*populate it through ViewBag*#
#*<select asp-for="Selected_Glossary" asp-items="ViewBag.Glossary_List"></select>*#
<input type="submit" value="Submit" />
</form>
Test Result
I have an mvc empty project where I'm trying to pull questions from the database based on what a user select from a title drop down (The values for the dropdown also come from the database).
I have the drop down working with hard coded values so far. How can I pull the titles from the database and how can I pull the questions associated with the title selected.
The auto generated model I have looks like this
namespace Demo1.Models{
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Web.Mvc;
public partial class Title
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Title()
{
TitlesQuestions = new HashSet<TitlesQuestion>();
}
public int TitleId { get; set; }
[Column("Title")]
[Required]
[StringLength(20)]
public string Title1 { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<TitlesQuestion> TitlesQuestions { get; set; }
public SelectList TitleList { get; set; }
}
My ViewModel
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
namespace Demo1.ViewModels.Titles
{
public class TitlesViewModel
{
public int TitleId { get; set; }
[Required]
[Display(Name = "Title")]
public string Title { get; set; }
public IEnumerable<SelectListItem> Titles { get; set; }
}
}
My Controller
using Demo1.Models;
using Demo1.ViewModels.Titles;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
namespace Demo1.Controllers
{
public class TitlesController : Controller
{
private EmployeeContext db = new EmployeeContext();
public IEnumerable<Title> GetTitleList()
{
var result = db.Titles.ToList();
return result;
}
// GET: Titles
public ActionResult Index()
{
var titles = GetAllTitles();
var model = new TitlesViewModel();
model.Titles = GetSelectListItems(titles);
return View(model);
}
private IEnumerable<string> GetAllTitles()
{
return new List<string>
{
"CEO",
"Project Manager",
"Technical Lead",
"Software Developer",
};
}
private IEnumerable<SelectListItem> GetSelectListItems(IEnumerable<string> elements)
{
var selectList = new List<SelectListItem>();
foreach (var element in elements)
{
selectList.Add(new SelectListItem
{
Value = element,
Text = element
});
}
return selectList;
}
}
}
My View
#model Demo1.ViewModels.Titles.TitlesViewModel
#{
ViewBag.Title = "Index";
}
<h2>Questions by Title Demo</h2>
<form asp-controller="Titles" asp-action="Index" method="post" class="form-horizontal" role="form">
<label asp-for="Title" class="col-md-2 control-label"></label>
<div>
#Html.DropDownListFor(m => m.Title, // 1. Store selected value in Model.Roles when page is rendered after postback,take selected value from Model.State.
Model.Titles, // 2. Take list of values from Model.Titles
"- Please select your title -", // 3. Text for the first 'default' option
new { #class = "form-control" }) #*// 4. A class name to assign to <select> tag*#
</div>
</form>
I'm using entity framework
private EmployeeContext db = new EmployeeContext();
I have a table named Titles
Here's my new ActionResult Index()
public ActionResult Index()
{
var model = new TitlesViewModel();
var titles = GetSelectListItems();
model.Titles = titles;
return View(model);
}
public IEnumerable<SelectListItem> GetSelectListItems()
{
foreach (var title in db.Titles)
{
yield return new SelectListItem
{
Value = title.TitleId.ToString(),
Text = title.Title1
};
}
}
When I try to run my project I get the following error
The class 'System.Web.Mvc.SelectList' has no parameterless constructor. I'm new to mvc so I'm not sure how to fix it. This seems like it should be a simple task I'm trying to bind data from the titles table to a drop down then once a title is selected I want the relevant questions from the database to show.
I think this is more of a question that involves on how to query a database. Overall this question needs alittle more context (what database is being used). Depending on what you're using there are many ways to query a database. My favorite for SQL is using ADO.NET Entity Data Model. This is a database first approach. It creates a .edmx that creates all the models from the tables you select when setting it up.
After Setup:
Access data entities
MyAccountEntities users = new MyAccountEntities();
Access tables(use LINQ to change DbSet<UserAccount> to List<UserAccount>) ;)
users.UserAccounts.ToList();
Use LINQ to query your table/list. (returns a list of users named bob)
string username = "bob";
users.UserAccounts.Where(u => u.username == username).ToList();
UPDATE!!!!
Thank you for narrowing your problem down. The problem is pretty straight-forward. You have no constructor that takes parameters for your SelectListItem model. Go to where the model is defined then create a constructor with the parameters you wish to pass it.
Hope this Helps. Cheers :)
I am getting started with MVC and I have the following Model
public class FormControls
{
//Properties of the FormControls object
public string formCName { get; set; }
public string formCType { get; set; }
public string formCCss { get; set; }
public string formCEnabled { get; set; }
public string formCDefaultVal { get; set; }
}
I also created the following control and I am querying a database using linq to select records. Each record will then have to be added to a list.
public ActionResult Index()
{
var DataContext = new EditProfileFormFieldsDataContext();
var controls = from c in DataContext.Controls
select c;
List<FormControls> Fields = new List<FormControls>();
foreach(var fc in controls)
{
//Create Object for Generic List
FormControls epc = new FormControls();
epc.formCName = fc.Control_Name;
epc.formCType = fc.Control_Type;
epc.formCCss = fc.Control_CSS;
epc.formCEnabled = fc.Control_Enabled;
epc.formCDefaultVal = fc.Control_DefaultVal;
//Add Object to FormControls Generic List
Fields.Add(epc);
}
return View("EditProfile");
}
My question is how would I access the list using RAZOR in the view? I am trying to loop through the list I created in the view. I am fairly new to MVC and I think I am over thinking a lot of this :) Thanks!
You can make the model of your view a List. Put this at the top of your view:
#model List<FormControls>
Change the return of your Index() method:
return View("EditProfile", Fields);
Then you can access it from the view by using #Model. For example, to iterate through it:
#foreach (var field in Model)
{
<p>#field.formCName</p>
}
Btw, there is a more direct way to implement the controller.
public ActionResult Index()
{
var DataContext = new EditProfileFormFieldsDataContext();
return View("EditProfile", DataContext.Controls.ToList());
}
or if you rename the view to "index.cshtml", you can do it like this:
public ActionResult Index()
{
var DataContext = new EditProfileFormFieldsDataContext();
return View(DataContext.Controls.ToList());
}
Suppose you do not have the index.cshtml yet, right click the "View(" and select "Add View", in the pop-up wizard, select "list view" and FormControls, there will be an auto-generated view with #model defined and a well done table demoing how to use it.
i recently had the dropdownlist working and everything was fine but for some reason it is now throwing value cannot be null exception. I have swapped variable names around and things trying to resolve the error but has had no effect. Could you please take a look at my code and point me in the right direction. I am a beginner with MVC4 and have been working on this problem for hours now, so any help would be appreciated. I have only posted relevant code thanks in advance.
EDIT: it is throwing the error at start of line #Html.DropDownListFor(....) in the view
Model:
public partial class SiteBookingsTable
{
public string departureAirport { get; set; }
public string arrivalAirport { get; set; }
[Required]
[Display(Name = "Flying From")]
public string chooseDepartureAirport { get; set; }
[Required]
[Display(Name = "Flying To")]
public string chooseArrivalAirport { get; set; }
}
View:
#model Project56.Models.SiteBookingsTable
#{
List<Project56.Models.SiteBookingsTable> selectDepFlight = ViewBag.depList;
}
<tr>
<td>#Html.LabelFor(model => model.chooseDepartureAirport)<br />
#Html.DropDownListFor(model => model.chooseDepartureAirport, new SelectList(selectDepFlight,"departureAirport","departureAirport"))</td>
</tr>
Controller:
public ActionResult Create()
{
List<SiteBookingsTable> selectDepFlight = new List<SiteBookingsTable>();
selectDepFlight.Add(new SiteBookingsTable() { listID = 0, departureAirport = "-Select-" });
selectDepFlight.Add(new SiteBookingsTable() { listID = 1, departureAirport = "London (LTN)" });
selectDepFlight.Add(new SiteBookingsTable() { listID = 2, departureAirport = "Manchester (MAN)" });
ViewBag.depList = selectDepFlight;
return View();
}
[HttpPost]
public ActionResult Create(SiteBookingsTable aBooking)
{
if (ModelState.IsValid == true)
{
newBooking.SiteBookingsTables.Add(aBooking);
newBooking.SaveChanges();
return RedirectToAction("Index");
}
return View(aBooking);
}
in your View you are using SelectList(selectDepFlight,
but you are sending a ViewBag variable ViewBag.depList = selectDepFlight;
you want SelectList(ViewBag.depList,
although honestly it should probably be in the Model, not the ViewBag
If I remember correctly the SelectList type must be enumerable. --Source
** Edit, its probably best to return the value as an enumerable from the controller side instead of in the View itself. Also consider utilizing ViewModels and not the Model itself.
List<Project56.Models.SiteBookingsTable> selectDepFlight = ViewBag.depList;
//Add the following line(s) to cast your list to an enumerable.
IEnumerable<Project56.Models.SiteBookingsTable> enumSelectDepFlight = selectDepFlight.AsEnumerable<Project56.Models.SiteBookingsTable>
//Alter the following code
#Html.DropDownListFor(model => model.chooseDepartureAirport, new SelectList(selectDepFlight,"departureAirport","departureAirport"))
//to match the enumerable above
#Html.DropDownListFor(model => model.chooseDepartureAirport, new SelectList(enumSelectDepFlight,"departureAirport","departureAirport"))
Unable to bind model with value from #Html.DropDownListFor field in MVC3 (razor) of a strongly typed view.
Model used for strongly typed view:
public class MyModel
{
public string Name{get;set;}
pulic int Status_ID{get;set;}
}
In strongly typed view:
#Html.DropDownListFor(m=> m.Status_ID, new SelectList(Repo.AllStatus, "ID", Name"), new {#style = "width: 100%;" })
Before submitting the form I selected the option with ID=24(i.e. value=24 option is selected)
In controller
public ActionResult AddMyModel(MyModel myModel)
{
}
While debugging, in controller, I got that:
myModel.Name is expected value but
myModel.Status_ID is 0 not 24
where am I going wrong??
You need to pass in a view model to your view with all the statuses already populated.
Here is a solution to your problem. Modify it to fit in with your scenario. I hope I haven't left out anything. The code below is what I am assuming your models might look like.
Your status class:
public class Status
{
public int Id { get; set; }
public string Name { get; set; }
}
On your view you need to pass in a view model that contains a list of all your statuses:
public class YourViewModel
{
public int StatusId { get; set; }
public IEnumerable<Status> Statuses { get; set; }
}
Your controller:
public class YourController : Controller
{
private readonly IStatusRepository statusRepository;
public YourController(IStatusRepository statusRepository)
{
this.statusRepository = statusRepository;
}
public ActionResult YourAction()
{
YourViewModel viewModel = new YourViewModel
{
Statuses = statusRepository.FindAll()
};
return View(viewModel);
}
}
And then your view will look something like this:
#model YourProject.ViewModels.Statuses.YourViewModel
#Html.DropDownListFor(
x => x.StatusId,
new SelectList(Model.Statuses, "Id", "Name", Model.StatusId),
"-- Select --"
)
#Html.ValidationMessageFor(x => x.StatusId)
I hope this can help you in the right direction and shed some light on what you are trying to achieve.