Invalid Arguments in Razor DropDownList - c#

I'm receiving an error that a dropdownlist has invalid arguments. What's odd is that I have a similarly structured dropdownlist that is working fine, with no errors. The drop down with the error is the second one (that displays the year):
View:
#{
string month = "TempEmployments[" + idx + "].EmploymentStartMonth";
string year = "TempEmployments[" + idx + "].EmploymentStartYear";
}
#Html.DropDownList(month, (IEnumerable<SelectListItem>)this.ViewBag.MonthList,EmploymentStartMonth, new { #class = "field panel-field EmploymentDate", #id = month })
#Html.ValidationMessageFor(model => model.EmploymentStart)
#Html.DropDownList(year, (IEnumerable<SelectListItem>)this.ViewBag.YearList, EmploymentStartYear, new { #class = "field panel-field EmploymentDate", #id = year })
Controller:
[HttpPost]
public ActionResult AddEmploymentHistory(int ApplicantID, int RecordNum)
{
this.ViewBag.RecordNum = RecordNum;
this.ViewBag.StateList = this.GetStateList();
this.ViewBag.MonthList = this.GetMonthList();
this.ViewBag.YearList = this.GetYearList();
return PartialView("_EmploymentHistoryPartial");
}
private IEnumerable<SelectListItem> GetYearList()
{
List<SelectListItem> yearList = new List<SelectListItem>();
int current_yr = Convert.ToInt32(DateTime.Now.Year.ToString());
int select_yr = 0;
for(int i = (current_yr-3); i <= current_yr; i++)
{
select_yr = current_yr - (i - (current_yr-3));
yearList.Add(new SelectListItem() { Value = select_yr.ToString(), Text = select_yr.ToString() });
}
return yearList;
}
private IEnumerable<SelectListItem> GetMonthList()
{
List<SelectListItem> monthList = new List<SelectListItem>();
monthList.Add(new SelectListItem() { Value = "JAN", Text = "Jan" });
monthList.Add(new SelectListItem() { Value = "FEB", Text = "Feb" });
monthList.Add(new SelectListItem() { Value = "MAR", Text = "Mar" });
monthList.Add(new SelectListItem() { Value = "APR", Text = "Apr" });
monthList.Add(new SelectListItem() { Value = "MAY", Text = "May" });
monthList.Add(new SelectListItem() { Value = "JUN", Text = "Jun" });
monthList.Add(new SelectListItem() { Value = "JUL", Text = "Jul" });
monthList.Add(new SelectListItem() { Value = "AUG", Text = "Aug" });
monthList.Add(new SelectListItem() { Value = "SEP", Text = "Sep" });
monthList.Add(new SelectListItem() { Value = "OCT", Text = "Oct" });
monthList.Add(new SelectListItem() { Value = "NOV", Text = "Nov" });
monthList.Add(new SelectListItem() { Value = "DEC", Text = "Dec" });
return monthList;
}

So I created a sample project with the data you provided and came up with this :
Controller
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
this.ViewBag.RecordNum = 1;
this.ViewBag.MonthList = this.GetMonthList();
this.ViewBag.YearList = this.GetYearList();
return PartialView();
}
private IEnumerable<SelectListItem> GetYearList()
{
List<SelectListItem> yearList = new List<SelectListItem>();
int current_yr = Convert.ToInt32(DateTime.Now.Year.ToString());
int select_yr = 0;
for (int i = (current_yr - 3); i <= current_yr; i++)
{
select_yr = current_yr - (i - (current_yr - 3));
yearList.Add(new SelectListItem() { Value = select_yr.ToString(), Text = select_yr.ToString() });
}
return yearList;
}
private IEnumerable<SelectListItem> GetMonthList()
{
List<SelectListItem> monthList = new List<SelectListItem>();
monthList.Add(new SelectListItem() { Value = "JAN", Text = "Jan" });
monthList.Add(new SelectListItem() { Value = "FEB", Text = "Feb" });
monthList.Add(new SelectListItem() { Value = "MAR", Text = "Mar" });
monthList.Add(new SelectListItem() { Value = "APR", Text = "Apr" });
monthList.Add(new SelectListItem() { Value = "MAY", Text = "May" });
monthList.Add(new SelectListItem() { Value = "JUN", Text = "Jun" });
monthList.Add(new SelectListItem() { Value = "JUL", Text = "Jul" });
monthList.Add(new SelectListItem() { Value = "AUG", Text = "Aug" });
monthList.Add(new SelectListItem() { Value = "SEP", Text = "Sep" });
monthList.Add(new SelectListItem() { Value = "OCT", Text = "Oct" });
monthList.Add(new SelectListItem() { Value = "NOV", Text = "Nov" });
monthList.Add(new SelectListItem() { Value = "DEC", Text = "Dec" });
return monthList;
}
}
}
View
#{
//string month = "TempEmployments[" + idx + "].EmploymentStartMonth";
//string year = "TempEmployments[" + idx + "].EmploymentStartYear";
}
#Html.DropDownList("some name", (IEnumerable<SelectListItem>)this.ViewBag.MonthList,"some label", new { #class = "field panel-field EmploymentDate", #id = "id" })
<!-- ##Html.ValidationMessageFor(model => model.EmploymentStart) No idea what your model is-->
#Html.DropDownList("some name2", (IEnumerable<SelectListItem>)this.ViewBag.YearList, "some label", new { #class = "field panel-field EmploymentDate", #id = "id2" })
And both dropdowns in my test worked 100% fine. This makes me believe that one either id, name, or label are not being populated correctly. The code you provided does not show how their values are created
Populate your second dropdown just like mine (with a dummy id, label, and name, and see if it renders. Then by process of elimination add them back in.
Also, just a general tip, I would be abstracting those classes out of your controller and into their own classes. Helps keep things a lot cleaner. As well as pass in viewmodels with all of your properties needed. This avoids "Magic strings" and allows code to be easier to update and debug.
As example instead of :
public ActionResult Index()
{
this.ViewBag.RecordNum = 1;
this.ViewBag.MonthList = this.GetMonthList();
this.ViewBag.YearList = this.GetYearList();
return PartialView();
}
I would do
public ActionResult Index()
{
var viewModel = new indexViewModel{
RecordNum = 1,
MonthList = _someService.GetMonthList(),
YearList = _someService.GetYearList()
}
return PartialView(viewModel);
}
then in your view you don't have to worry about magic strings. you can simply do
#Model.MonthList

if I had to guess it has to do with a viewbag being used for a partial view after the page load. Viewbag has its uses but it isn't recommended for drop downs. I would recommend that you build a view model for your partial
public Class EmploymentHistory{
public EmploymentHistory(){
StateList = new List<SelectListItem>();
MonthList = new List<SelectListItem>();
YearList = new List<SelectListItem>();
}
public string RecordNum { get; set; }
public List<SelectListItem> StateList { get; set; }
public string SelectedState { get; set; }
public List<SelectListItem> MonthList { get; set; }
public string SelectedMonth { get; set; }
public List<SelectListItem> YearList { get; set; }
public string SelectedYear { get; set; }
}
then on your controller instead of setting the view bag set the model
EmploymentHistory eh = new EmploymentHistory();
eh.StateList = GetStateList();
etc...
and you can set the defaults for the dropdowns on the controller
eh.SelectedState = //Default value;
return PartialView("_EmploymentHistoryPartial", eh);
on the top of your partial
#model EmploymentHistory
and then change your dropdowns to
#Html.DropDownList(SelectedState, model.StateList, new { #class...
or
#Html.DropDownListFor(x => x.SelectedState, model.StateList, new { #class...

Related

How to select value from selectlist?

How to select a text from selectlist? I want to auto select name "Dave" name from back-end on line First_Name_SELECT = "Dave";
<select asp-for="Person.First_Name" asp-items="#Model.First_Name_SELECT">
</select>
[BindProperty(SupportsGet = true)]
public string? First_Name { get; set; }
public SelectList? First_Name_SELECT { get; set; }
First_Name_SELECT = new SelectList(await _services.Get_Names());
First_Name_SELECT = "Dave";
public async Task<List<string>> Get_Names()
{
IQueryable<string> Query = (from m in _context2.Names_DbSet
select m.First_Names).Distinct().OrderBy(m => m);
return await Query.ToListAsync();
}
** UPDATE ** Following code works fine below but why First_Name_SELECT doesn't work? is this becuase I am using IQueryable?
[BindProperty(SupportsGet = true)]
public string? Last_Name { get; set; }
public SelectList? Last_Name_SELECT { get; set; }
Last_Name_SELECT = new SelectList(await _services.Get_LastNames());
var testing = Last_Name_SELECT .Where(x => x.Value.Contains("Name8")).FirstOrDefault();
testing.Selected = true;
public List<SelectListItem> Get_LastNames()
{
List<SelectListItem> Query = new List<SelectListItem>
{
new SelectListItem() { Selected =true, Value = "name1", Text = "name1" },
new SelectListItem() { Value = "name2", Text = "name2" },
new SelectListItem() { Value = "name3", Text = "name3" },
new SelectListItem() { Value = "name4", Text = "name4" },
new SelectListItem() { Value = "name5", Text = "name5" },
new SelectListItem() { Value = "name6", Text = "name6" },
new SelectListItem() { Value = "name7", Text = "name7" },
new SelectListItem() { Value = "name8", Text = "name8" },
new SelectListItem() { Value = "name9", Text = "name9" }
};
return Query;
}
If you have a model Person, you can try the below code:
var First_Name_SELECTSelectedValue = "Dave";
First_Name_SELECT = new SelectList(await _services.Get_Names(), First_Name_SELECTSelectedValue);
result:
You can read SelectList(IEnumerable, Object) to know more.
public SelectList (System.Collections.IEnumerable items, object
selectedValue);

Set the selected value for a DropDownList using SelectListItem

Although this question has been asked for several times, still I am struggling to find a solution for a problem
I have a drop down and i want to bind the selected value when retrieving data.
here is my controller
studentList = db.Students
.Select(x => new SelectListItem
{
Value = x.StudentId.ToString(),
Text = x.StudentNo + " - " + x.StudentNameEn
}).ToList();
ViewData["studentList"] = studentList;
here is my view
#Html.DropDownList("StudentNo", ViewData["studentList"] as List<SelectListItem>, "---Please Select---", new { #class = "form-control selectpicker", id = "studentIdDrp" })
What I have tried
I tried to bind the value using jquery
$("#studentIdDrp").val('#Model.AppointmentViewModel.FK_StudentId');
I tried from the controller to set the selected attribute true
foreach(var item in studentList)
{
if (item.Value == appoinmnetRec.FK_StudentId.ToString())
{
item.Selected = true;
}
}
None of the above methods working. Please help, thanks in advance
I tried to reproduce your issue. In my machine, selected value worked.
Controller:
namespace WebApplication2.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Title = "Home Page";
var studentList = new List<SelectListItem>()
{
new SelectListItem {Text = "ABC", Value = "1"},
new SelectListItem {Text = "CDE", Value = "2"},
};
ViewData["studentList"] = studentList;
return View();
}
public ActionResult Student()
{
var studentList = new List<SelectListItem>()
{
new SelectListItem {Text = "Peter Cech", Value = "S001"},
new SelectListItem {Text = "Leo Messi", Value = "S002"},
};
ViewData["studentList"] = studentList;
AppointmentViewModel model = new AppointmentViewModel();
model.FK_StudentId = "S001";
return View(model);
}
}
public class AppointmentViewModel
{
public string FK_StudentId { get; set; }
}
}
View: Student.cshtml
#model WebApplication2.Controllers.AppointmentViewModel
#{
ViewBag.Title = "Student";
}
<h2>Student</h2>
<script src="~/Scripts/jquery-1.10.2.js"></script>
#Html.DropDownList("StudentNo", ViewData["studentList"] as List<SelectListItem>, "---Please Select---", new { #class = "form-control selectpicker", id = "studentIdDrp" })
<script>
$(document).ready(function () {
$("#studentIdDrp").val('#Model.FK_StudentId');
});
</script>

Pass DropDown List Value from View to Controller

I need to Pass a Value selected from drop down in a View to a Controller and as of now I am failing miserably.
How should I do that?
Following is my code for the View:
#model NurseOneStop.SC.NurseProfile
#{
ViewBag.Title = "Settings";
}
<h2>Settings</h2>
<div class="col-lg-8 col-md-6 profile_detail">
<h3>#Model.Title #Model.FirstName</h3>
<p><span>Profession:</span> #Model.Profession</p>
<p><span>Contact No:</span> <b>#Model.PhoneNumber </b>
<p><span>Email ID:</span> <b>#Model.EmailId </b>
<br />
<br />
<br />
<br />
<div>
<div>
<h5>Visibility Settings for Profile</h5>
#Html.DropDownList("Profile_Settings", new List<SelectListItem>
{
new SelectListItem{ Text="Public", Value = "1" },
new SelectListItem{ Text="Friends Only", Value = "2" },
new SelectListItem{ Text="Private", Value = "3" }
}, "Select Visibility Type")
</div>
<button class="profile_btn">#Html.ActionLink("Save Settings", "UpdateSettings")</a></button>
</div>
</div>
Below is my Controller for the same:
public ActionResult UpdateSettings()
{
NurseProfile objNurseProfile = new NurseProfile();
Int64 NurseId = ApplicationSession.CurrentUser.NurseId;
if (NurseId != 0)
{
//objNurseProfile = objNurseDAL.UpdateProfileVisibility(NurseId, ProfileVisibility);
}
return View(objNurseProfile);
}
Try it with the following code:
[HttpGet]
public ActionResult Settings(Int64? id, string returnUrl)
{
List<Keyword> objKeywordList = new List<Keyword>();
List<SelectListItem> ProfileVisibility = new List<SelectListItem>();
NurseProfileVisibility objNurseProfileVisibility = new NurseProfileVisibility();
Int64 NurseId = ApplicationSession.CurrentUser.NurseId;
objNurseProfileVisibility.NurseId = NurseId;
SelectListItem objSelect = new SelectListItem { Text = "Profile Visibility", Value = "", Selected = true };
objKeywordList = objKeywordDAL.GetKeywordsByType("ProfileVisibility").Results;
var visibilityOption = (from kl in objKeywordList
select new SelectListItem
{
Text = kl.KeywordText,
Value = kl.KeywordValue.ToString(),
Selected = false
}).ToList();
if (id != 0)
{
Result res = objNurseDAL.GetProfileVisibilityById(NurseId);
if (res.Status)
{
if(res.Results != null) {
objNurseProfileVisibility = res.Results;
if (objNurseProfileVisibility.NurseId != NurseId)
{
visibilityOption.FirstOrDefault(x => x.Value == objNurseProfileVisibility.ProfileVisibilityId.ToString()).Selected = true;
}
}
}
}
ViewBag.VisibilityOptions = visibilityOption;
ViewBag.returnUrl = returnUrl;
return View(objNurseProfileVisibility);
}
You need to store the values into the Database and parse them from there using List and DAL's.
You can use razor to fill a dropdownlist like this and then send it via the Model (like MVC dictates).
#{
List<SelectListItem> listItems= new List<SelectListItem>();
listItems.Add(new SelectListItem
{
Text = "Public",
Value = "1"
});
listItems.Add(new SelectListItem
{
Text = "Friends Only",
Value = "2"
});
listItems.Add(new SelectListItem
{
Text = "Private",
Value = "3"
});
}
#Html.DropDownListFor(model => model.profileSettings, listItems, "Select Option")
#Html.ActionLink(
"Save Settings", // linkText
"UpdateSettings", // actionName
"Settings", // controllerName
new { // routeValues
SomeModel = Model
},
null // htmlAttributes
)
And you should have your model in your method like so:
public ActionResult UpdateSettings(SomeModel model)
{
int setting = model.profileSettings; //your choice
return View(objNurseProfile);
}
And create a model like so:
public class SomeModel
{
[Required]
public int profileSettings { get; set; }
}

How to check if dropdown list values matches with table country list in C#?

I have dropdownlist for country where it contains 6 countries. But I have a country table as well where I have more than 100 countries.
Now I want to check whether CountryId exists in dropdown list or not. If CountryId does not exists then by default choose first from dropdown list.
Any help is highly appreciated. Please show the way to do this?
Model
public int? Country { get; set; }
public IEnumerable<SelectListItem> CountriesList { get; set; }
Controller
var country = db.Country.SingleOrDefault(u => u.CountryId == user.CountryID)
int CountryId = countrylist.CountryId;
CountriesList = new List<SelectListItem>
{
new SelectListItem { Value = "1", Text = "India" },
new SelectListItem { Value = "2", Text = "Pakistan" },
new SelectListItem { Value = "3", Text = "Nepal" },
new SelectListItem {Value = "4", Text = "Sri Lanka" },
new SelectListItem { Value = "5", Text = "Bangladesh" },
new SelectListItem {Value = "6", Text = "Bhutan" },
}
View
#Html.DropDownListFor(m => m.Country, Model.CountriesList, new { #class = "form-control" })
If you set the Country property value of your view model to the country id, the helper will select the corresponding option when the SELECT element is rendered.
You can check the specific countryId value exist in the CountriesList property of your view model using the Any method.
The SingleOrDefault method will return NULL when there are no records matching your where condition. So do a null check on that as well.
public ActionResult Create()
{
var vm = new CreateVm();
vm.CountriesList = new List<SelectListItem>
{
new SelectListItem { Value = "1", Text = "India" },
new SelectListItem { Value = "2", Text = "Pakistan" },
new SelectListItem { Value = "3", Text = "Nepal" },
new SelectListItem {Value = "4", Text = "Sri Lanka" },
new SelectListItem { Value = "5", Text = "Bangladesh" },
new SelectListItem {Value = "6", Text = "Bhutan" }
};
// user object is intstantiated somehave
var country = db.Country.SingleOrDefault(u => u.CountryId == user.CountryID);
if (country != null && vm.CountriesList
.Any(a => a.Value == country.CountryId.ToString()))
{
vm.Country = country.CountryId;
}
else
{
vm.Country = 1; // Value of "India" option (select list)item
}
return View(vm);
}

How Do I Bind Values From DropDownListFor To My Controller?

I have a select control with static values in my view and I intend the user select a value and it binds to my controller so I can use it in the required action method.
My View -
#model StockProject.ViewModels.EquityViewModel
#using (Html.BeginForm(FormMethod.Post)){
#{
var selectList = new SelectList(
new List<SelectListItem>
{
new SelectListItem {Text = "BOOKED", Value = "1"},
new SelectListItem {Text = "EXECUTING", Value = "2"},
new SelectListItem {Text = "EXECUTED", Value = "3"},
new SelectListItem {Text = "SUSPENDED", Value = "4"},
new SelectListItem {Text = "CANCELLED", Value = "5"},
}, "Value", "Text");
}
#Html.DropDownListFor(model => model.status, selectList, new { #class = "form-control", name = "status", id = "status" })
<div class="col-md-3 form-group">
<button type="button" class="btn btn-success btn-block form-control" onclick="location.href='#Url.Action("Equity", "Order")'">
Go
<i class="fa fa-arrow-circle-right"></i>
</button>
</div>
}
ViewModel -
public class EquityViewModel
{
public int CustomerId { get; set; }
public string status { get; set; }
public DateTime startdate { get; set; }
public DateTime enddate { get; set; }
public List<ListEquityOrder> ListOrderEquity { get; set; }
public EquityViewModel()
{
ListOrderEquity = new List<ListEquityOrder>();
}
}
Controller -
[HttpGet]
public IActionResult Equity()
{
var modelview = new EquityViewModel();
var model = new EquityRequest();
model.CustomerId = _appSettings.TestCustomerId;
model.RequestStartPoint = 0;
model.NoOfRequests = 1000000;
model.Null = null;
model.Status = modelview.status;
model.StartDate = modelview.StartDate;
model.EndDate = modelview.EndDate;
model.Equity = "EQUITY";
EquityResponse ListEquityOrders = _genericService.CallSoapAction<EquityResponse, EquityRequest>(model, "findCustomerOrdersBySecurityType");
List<ListEquityOrder> findCusOrder = new List<ListEquityOrder>();
foreach (var t in ListEquityOrders.Item)
{
ListEquityOrder listOrder = new ListEquityOrder();
listOrder.BusinessOffice = t.BusinessOffice;
listOrder.CustomerLabel = t.CustomerLabel;
listOrder.CustomerName = t.CustomerName;
listOrder.Exchange = t.Exchange;
listOrder.FixOrderStatus = t.FixOrderStatus;
//adding other data values to the list
findCusOrder.Add(listOrder);
}
modelview.ListOrderEquity = findCusOrder;
return View(modelview);
}
Anytime the user clicks on the submit button, no values are passed the controls - the DropDownListFor and TexBoxes. I have tried FormCollection but that doesn't work. Please how do I resolve this?
You can use the following code getting the expected output.
In your model
public enum BookingDetails
{
BOOKED = 1, EXECUTING = 2, EXECUTED = 3, SUSPENDED = 4, CANCELLED = 5
}
public class SomeModel
{
public BookingDetails bookingDetails { get; set; }
public static IEnumerable<SelectListItem> GetBookingDetailsSelectItems()
{
yield return new SelectListItem { Text = "BOOKED", Value = "1" };
yield return new SelectListItem { Text = "EXECUTING", Value = "2" };
yield return new SelectListItem { Text = "EXECUTED", Value = "3" };
yield return new SelectListItem { Text = "SUSPENDED", Value = "4" };
yield return new SelectListItem { Text = "CANCELLED", Value = "5" };
}
}
Note : The above model only deals with dropdown values. If you want to do more then fell free to extend the class
Then your controller should be like below
public class MyController : Controller
{
// GET: My
public ActionResult MyAction()
{
// shows your form when you load the page
return View();
}
[HttpPost]
public ActionResult MyAction(SomeModel model)
{
var selectedBookingDetails = model.bookingDetails;// this will be the selected dropdown item text.
return View(model);
}
}
then view
#model SomeModel
#using (Html.BeginForm("MyAction", "My", FormMethod.Post))
{
#Html.DropDownListFor(m => m.bookingDetails, SomeModel.GetBookingDetailsSelectItems())
<input type="submit" value="Send" />
}
Note : please include the correct namespace of model

Categories