I have something like this in my code and I am getting error: Exception Details: System.ArgumentException: Value cannot be null or empty.
Parameter name: name . What am I doing wrong ? Thanks for help
#model IEnumerable<NHibernateFluentProject.Patient>
#Html.ListBoxFor(model => model, new SelectList(Model,"ID", "FirstName"));
#Html.ListBoxFor is used for your strong typed viewmodel. which could help to bind to your property. First part will take a lambda expression for a single item as a default seleced for your listbox, second part will take the item collections to dispaly all the listbox items.
For example: you have following two classes.
public class HospitalViewModel
{
public string SelectedPatient { get; set; }
public IEnumerable<Patient> AllPatients { get; set; }
}
public class Patient
{
public int Id { get; set; }
public string FirstName { get; set; }
}
From you view, you should do something like
#model HospitalViewModel
#Html.ListBoxFor(model => model.SelectedPatient, new SelectList(Model.AllPatients,"Id", "FirstName"));
OR if you only want to bind all your patients to a listbox, then use Html.ListBox instead
#model IEnumerable<Patient>
#Html.ListBox("ListBoxName", new SelectList(Model,"Id", "FirstName"));
You need to pass a lambda expression containing the property to bind the listbox to.
Related
I have a strongly typed view, which hold controls(input boxes) to represent a collection item. So for an example , take case of a view for adding an Employee detail and within that there are variable set of input fields to enter Department name. These input fields are to be added dynamically at client side.
Here is the class structure of these two entities:
public class Employee
{
public int EmployeeID{get;set;}
public string Name {get;set; }
public IList<Department> DepartmentList{get;set;}
}
public class Deparment {
[Required(ErrorMessage="This is a required Field")]
public string Name {get;set; }
public int ID { get;set; }
}
Inputs for department names are generated dynamically and names are set in a way to achieve model binding after posting
<input type='text' class='input-choice' id='txtChoice0' name='Department[0].Name' />
Now my question is how should I apply validation to this ?. Microsoft Validation won't push the validation inside the mvcClientValidationMetadata , reason for this I assume is that framework doesn't see any model binding happening at the time of view load.
Any ideas ??
I believe what you are asking for is how to validate values from the dropdownlist with 'Required' attribute. You will need to make some changes to the Employee model.
First of all you will need a 'DepartmentCode' property coz you will be storing the selected Department code from the dropdown.
Then you can have the DepartmentList as IEnumerable<SelectListItem>
so your Employee model will look like
public class Employee
{
public int EmployeeID{get;set;}
public string Name {get;set; }
[Required(ErrorMessage = "Please select a department")]
public string DepartmentCode { get; set; }
public IEnumerable<SelectListItem> DepartmentList{get;set;
}
you can get the DepartmentList like this
public IEnumerable<SelectListItem> DepartmentList
{
get
{
//Your code to return the departmentlist as a SelectedListItem collection
return Department
.GetAllDepartments()
.Select(department => new SelectListItem
{
Text = department.Name,
Value = department.ID.ToString()
})
.ToList();
}
}
finally in the view
<%: Html.DropDownListFor(model => model.DepartmentCode, Model.DepartmentList, "select")%>
<%: Html.ValidationMessageFor(model => model.DepartmentCode)%>
Now when you try to submit without selecting a department it should be validated
I am going to develop a search page where I will have multiple fields comming from differenet models (entity). Also, I have multiple DropDownLists on the same screen whose values will be populated from a lookup table.
I would like to know (in this scenario) what is the best approach. Should I create a ViewModel and pass that model to my view? Or do I need a different approach?
But I am not sure how I should handle my dropdown field, which is populating from lookup table.
Also, on submitting the page, how should I get those values in my next search details screen to get all the records from db?
I am using MVC3 with EF 4.2
Having a ViewModel with necessary properties ( your search criteria) is the way to go.
When you do a HttpGet action for your search load all datas from the look up tables and load to the properties ( ex : States etc..).
public ActionResult Search()
{
SearchViewModel objVM=new SearchViewModel();
objVM.States=MyService.GetStates();
objVM.Type=MyService.GetUserTypes();
return objVM.
}
[HttpPost]
public ActionResult Search(SearchViewModel objVM)
{
if(ModelState.IsValid)
{
//Go for the search and return results
}
return View(objVm);
}
Absolutely, the best approach is definitely to use a ViewModel. Something like this would suffice:
public class Model1
{
public string Prop1 { get; set; }
}
public class Model2
{
public string Prop2 { get; set; }
}
public class ViewModel1
{
public Model1 Model1 { get; set; }
public Model2 Model2 { get; set; }
public SelectList DropDownItems { get; set; }
}
You'd populate the SelectList with an amount of SelectListItem objects in your Controller's Action Method that will pass this ViewModel to the View.
I'm having a problem handling multiple values from a strongly typed Listbox.
I have an Event Class that can have multiple Technology classes.
Here's my simplified Event class:
public class Event
{
public int ID { get; set; }
public IEnumerable<Technology> Technologies { get; set; }
}
I was using this
public List<Technology> Technologies { get; set; }
and changed to
public IEnumerable<Technology> Technologies { get; set; }
but still got the same error.
Here's the Technology class, it's a really simple one
public class Technology
{
public int ID { get; set; }
public String Description{ get; set; }
}
here's my simplified Controller
public ActionResult Create()
{
var TechnologyQry = from d in db.Technology
orderby d.Description
select new { d.ID, d.Description };
ViewBag.eventTechnology = new MultiSelectList(TechnologyQry ,"ID","Description");
return View();
}
and here's the view portion that renders the ListBox
#Html.ListBoxFor(model => model.Technologies, (MultiSelectList)ViewBag.eventTechnology)
and thit's the error I'm getting
The ViewData item that has the key 'Technologies' is of type 'System.Collections.Generic.List`1[[stuff.Models.Technology, stuff, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' but must be of type 'IEnumerable'./
Sorry, English is not my main language.
I'd appreciate any help I can get.
Thank you.
What Model have do you have defined in the View #model ...?
Besides that, the Create method isn't returning something to be used for/as the model.
If you want the listbox to be called "Technologies" in the name attribute, you could instead use:
#Html.ListBox("Technologies", (MultiSelectList)ViewBag.eventTechnology)
Too often I find myself including a list of options in a view model, each option being a view model itself of the raw option, with an added Selected property. Then, when processing the posted view model in an action, I need to iterate over the options list to find the selected item(s). Is there no tidier way of doing this, or is that what my spare time this Sunday afternoon is for?
One option is to use a combination of the selected value along with an associated SelectList on your view model.
For example, if you have a product which needs to be assigned a category, you might have a view model that looks similar to this:
public class ProductViewModel
{
public int SelectedCategoryId { get; set; }
public IEnumerable<CategoryViewModel> AllCategories { get; set; }
public SelectList CategorySelectList
{
get
{
return new SelectList(this.AllCategories, "Id", "Name", this.SelectedCategoryId);
}
}
//Other properties
}
public class CategoryViewModel
{
public int Id { get; set; }
public string Name { get; set; }
//Other properties
}
And an Html input helper in your view that looks like this:
#Html.DropDownListFor(mod => mod.SelectedCategoryId, Model.CategorySelectList, "---")
Because the CategorySelectList property on the ProductViewModel is given the SelectedCategoryId as the selectedValue parameter, you don't need to worry about manually setting the selected value anymore--it will do it for you when it renders the drop-down list.
I'm after a little help with the techniques to use for Databinding. It's been quite a while since I used any proper data binding and want to try and do something with the DataGridView. I'm trying to configure as much as possible so that I can simply designed the DatagridView through the form editor, and then use a custom class that exposes all my information.
The sort of information I've got is as follows:
public class Result
{
public String Name { get; set; }
public Boolean PK { get; set; }
public MyEnum EnumValue { get; set; }
public IList<ResultInfos> { get; set; }
}
public class ResultInfos { get; set; }
{
public class Name { get; set; }
public Int Value { get; set; }
public override String ToString() { return Name + " : " Value.ToString(); }
}
I can bind to the simple information without any problem. I want to bind to the EnumValue with a DataGridViewComboBoxColumn, but when I set the DataPropertyName I get exceptions saying the enum values aren't valid.
Then comes the ResultInfo collection. Currently I can't figure out how to bind to this and display my items, again really I want this to be a combobox, where the 1st Item is selected. Anyone any suggestions on what I'm doing wrong?
Thanks
Before you bind your data to the grid, first set the DataGridViewComboBoxColumn.DataSource like this...
combo.DataSource = Enum.GetValues(typeof(YourEnum));
I generally do this in the constructor after InitializeComponent(). Once this is set up you will not get an exception from the combo column when you bind your data. You can set DataGridViewComboBoxColumn.DataPropertyName at design time as normal.
The reason you get an exception when binding without this step is that the cell tries to select the value from the list that matches the value on the item. Since there are no values in the list... it throws an exception.