MVC3 cannot validate dropdownfor - asp.net-mvc

Not sure if i'm populating my dropdown correctly but I'm having issue validating the values in my dropdownlist. When a value has been selected it's still showing error 'The value x is invalid'. The type is of int? as I know int doesn't work with the validator.
View model code:
[Display(Name = "Category")]
[Required(ErrorMessage = "Category is required.")]
public AWS.DTO.Lookup Category { get; set; }
public IEnumerable<AWS.DTO.Lookup> Categories { get; set; }
Controller code:
[PageOptions(Title = "Create FMR")]
public ActionResult Create()
{
var model = new FMRRequestViewModel();
model.Categories = new AWS.BL.Lookup().GetFMRCategories();
return View(model);
}
Lookup Type:
public class Lookup
{
public int? ID { get; set; }
public string Description { get; set; }
}
View code:
#Html.DropDownListFor(m => m.Category, new SelectList(Model.Categories, "ID", "Description", -1), "-- Please Select -- ")
Thanks in advance for any help.

DropDown's don't work that way. A dropdown can only send the ID, not the text. You are passing the whole Category object to DropDownListFor, which it won't understand.
#Html.DropDownListFor(m => m.Category.ID, new SelectList(Model.Categories, "ID", "Description", -1), "-- Please Select -- ")

It's not going to bind to a Lookup model once selected. MVC doesn't work like ASP where you receive back an object (ASP you'd "bind" an enumerable of objects and, when selected, the whole object was returned--this is not the case in mvc, only the key will be returned (or whatever property was mapped as the dropdown's value)).
Instead you'd have to accept an Int32 then in your action retrieve the matching Lookup. So, in short:
change your ViewModel so Category is an Int32/int (and not a Lookup object).
in the receiving action map the Lookup based on what Category has for a populated value.

Related

MVC DisplayTemplate for Lookup list

I am calling a partial view on which I want to collapse a few dropdown controls(previously created by using DropDownListFor). Because the controls are readonly, I just need to show the selected value on each control. I have created a list called "salutations" in the controller, and pass it as ViewData to my partial view. On the partial view I need to see the selected salutation (e.g.. Mr/Miss/Dr)in my div using #Html.DisplayFor. I tried creating a DisplayTemplate according to an online posting, but I am still having issues getting this to work.
Lookup list declared like this in controller:
var salutations = (IEnumerable<lu_Salutation>)ViewData["salutations‌​"];
Here's my DisplayTemplate named LookupList.cshtml:
#model int
#using System.Linq
#vEmployee.SelectList1.Single(s => s.Value == Model.ToString()).Text
Of course, there's something wrong with the last line of the above code. vEmployee is the name of my model. How do I correct it?, and can I have a generic display template like the GridForeignKey Kendo EditorTemplate so I could easily pass the foreign key, the DisplayTemplate, and the lookup list to get just the text of the selected lookup value displayed?
Ideally, I will just like to have in my partial view, something like:
#Html.DisplayFor(model => model.id, "LookupList", SelectList((IEnumerable)ViewData["salutationList"], "TitleID", "Title"))
where TitleID and Title are respectively the value and text in the lookup list.
Models
public class lu_Salutation
{
public int TitleID { get; set; } // e.g. 1
public string Title { get; set; } // e.g. Mrs
}
ViewModel Class - I want to use just IDs here, but display the matching Texts from the lookup tables (e.g lu_Salutation) when needed
public class vEmployee
{
[Key]
public int EmployeeID { get; set; }
public int SalutationID { get; set; }
}
Controller
[HttpGet]
public ActionResult EmployeeDetails(int employeeID)
{
vEmployee SelectedEmployee = GetEmployees(employeeID).First();
ViewData["salutations"] = _db.lu_Salutation.OrderBy(e => e.Title);
return PartialView("_EmployeeDetails", SelectedEmployee);
}
private IEnumerable<vEmployee>GetEmployees(int employeeID)
{
IEnumerable<vEmployee> emp = (from e in _db.Employees
join c in _db.Contacts on e.EmployeeID equals c.EmployeeID
join u in _db.lu_Salutation on c.SalutationID equals u.TitleID into sal
from u in sal.DefaultIfEmpty()
where (e.EmployeeID == employeeID))
select new vEmployee
{
EmployeeID = e.EmployeeID,
SalutationID = c.SalutationID
}).AsEnumerable().OrderBy(m => m.EmployeeNumber).ThenBy(m => m.FirstName);
return emp;
}

Is it possible to create an Html.DropDownListFor directly from an entity model?

I have an IEnumerable of managers Model.managers from this I want to grab the ID value which would be managers.manager_id and the text value which would be managers.manager_name I also have a selected manager value at Model.SelectedManager which holds the manager_id
What I am trying to do is to stuff all of these values into an Html.DropDownListFor
It would need to be a list of all of the manager_id and manager_name and then automatically select the manager stored at Model.SelectedManager is this possible the way I have set it up?
public string SelectedManager { get; set; }
public virtual IEnumerable<managements> managers { get; set; }
I believe you are trying to do the following:
In a service layer (or the controller), you grab a List of SelectListItem from that managers IEnumerable:
model.ManagerList = managers.Select(i => new SelectListItem()
{
Text = i.manager_name,
Value = i.manager_id.ToString()
}).ToList());
Then, in your view model, you need that SelectedManager for Id and this manager list (of SelectListItem):
public string SelectedManager { get; set; }
public List<SelectListItem> ManagerList {get; set;}
and in your view, you use the ManagerList object with the razor helper:
#Html.DropDownListFor(m => Model.SelectedManager, Model.ManagerList,
new {#class = "form-control input-sm whatever-css-class"})
Hope this helps.
Edit: I have always used the selected id as an int and not a string. So I have not tested it as a string actually, and you may want to use it as int if string does not work.

mvc enum radio button required field

I am displaying radio buttons using enum class.
public enum RegisteredBy
{
[Display(Name = "Customer", Order = 0)]
H,
[Display(Name = "Dealer/Contractor", Order = 1)]
S,
}
When i am rendering this on my view and on submit I am not selected any radio button. Even though it is taking "H" as default value. So that it is not showing any validation message.
#using ConsumerProductRegistration.Models;
#using ProductRegistration.Models.Enums;
#model ProductRegistration.Models.Registration
#Html.RadioButtonFor(m => m.RegisteredBy, RegisteredBy.H, new { id = "RegisteredByCustomer" })
#Html.Label("Customer")<br />
#Html.RadioButtonFor(m => m.RegisteredBy, RegisteredBy.S, new { id = "RegisteredByDealer" })
#Html.Label("Dealer/Contractor")
#Html.ValidationMessageFor(m => m.RegisteredBy)
In Model:
public class Registration
{
[Required(ErrorMessage = "Select at least one option")]
[Display(Name = "Registered by*")]
public RegisteredBy RegisteredBy { get; set; }
}
In view:
public ActionResult CustomerInfo(Registration registration)
{
return View(registration);
}
please suggest me.If user does not select we should show the error message.
The default underlying type of the enumeration elements is int. By default, the first enumerator has the value 0, and the value of each successive enumerator is increased by 1.
When you are not selecting anything and posting the form, the default value 0 is automatically getting set (default value of integer).
In this case, you can make your property nullable with [Required] attribute which sends null as value when nothing is selected. And as it is decorated with [Required] attribute, it will give you required field validation error.
[Required]
public RegisteredBy? RegisteredBy { get; set; }

The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[System.Int32]'

ASP.Net MVC 4
I am trying to populate a list of Countries (data from Country table in DB) in a dropdownlist. I get the following error:
The model item passed into the dictionary is of type
System.Collections.Generic.List`1[System.Int32]', but this dictionary requires a model item of type 'BIReport.Models.Country'.
I am new to ASP.Net MVC and I don't understand that error. What I feel is what Index method is returning doesn't match with the model that I am using in the View.
Model::
namespace BIReport.Models
{
public partial class Country
{
public int Country_ID { get; set; }
public string Country_Name { get; set; }
public string Country_Code { get; set; }
public string Country_Acronym { get; set; }
}
}
Controller::
public class HomeController : Controller
{
private CorpCostEntities _context;
public HomeController()
{
_context = new CorpCostEntities();
}
//
// GET: /Home/
public ActionResult Index()
{
var countries = _context.Countries.Select(arg => arg.Country_ID).ToList();
ViewData["Country_ID"] = new SelectList(countries);
return View(countries);
}
}
View::
#model BIReport.Models.Country
<label>
Country #Html.DropDownListFor(model => model.Country_ID, ViewData["Country_ID"] as SelectList)
</label>
Where am I going wrong?
You are selecting CountryIDs, therefore you will have a list of integers passed into the view.
I think you really want something like this:
public ActionResult Index()
{
var countries = _context.Countries.ToList();
ViewData["Country_ID"] = new SelectList(countries, "Country_ID", "Country_Name");
return View();
}
I'm not really sure why you have single country as a model for your view.
Update:
I'm still not sure why the model is a country, if you are just going to post the ID of the selected country you don't necessarily need a model at all (or just have an integer). This will be just fine though:
View
#model MvcApplication1.Models.Country
#Html.DropDownListFor(m => m.Country_ID, ViewData["Country_ID"] as SelectList)
the problem is in line 1 of your view. change it like this :
#model IEnumerable<BIReport.Models.Country>
also there is no need to pass the model to view if you already did it by :
ViewData["Country_ID"] = new SelectList(countries);
When you say #model BIReport.Models.Country it means your view is expecting a model consisting single country details. On the contrary you need a list of countries to be displayed in the drop-down list. Hence you should tell the view to look for a list of country details instead.
Therefore #model IEnumerable.

Populate a dropdown list from db

I have an mvc 3 application with 2 tables in my entity framework.
PurchaseTable which was PurchaseID,PurchaseDate & ProductID I have another table called Product which contains ProductID and ProductName. creating a new view to insert a new purchase how do I change the textbox in the view for ProductID to be a dropdown bound by the ProductName in the Product table?
Create a ViewModel:
public class CreatePurchaseViewModel
{
public Purchase Purchase { get; set; }
public IEnumerable<SelectListItem> Products { get; set; }
public int SelectedProductId { get; set; }
}
Setup the View with the ViewModel:
[HttpGet]
public ActionResult CreateProduct()
{
var model = new CreatePurchaseViewModel
{
Products = repository.FindAllProducts().Select(x =>
new SelectListItem
{
Text = x.ProductName,
Value = x.ProductId
}
};
return View(model);
}
Then simply bind to the ViewModel and use the DropDownListFor HTML Helper:
<! -- other code to bind to Purchase, and then: -->
<%= Html.DropDownListFor(x => x.SelectedProductId, Model.Products) %>
Then when you submit the form, the SelectedProductId value in the model will be populated with the selected value from the dropdown list.
The answer is easier than it looks. Simply create a list:
myDropDown = new SelectList(db.Products, "Product_ID", "ProductName", idSelected);
The first parameter is your table ("Products" from the Entity Model), the second is the "id" that will be returned when selecting from the list (i.e SelectedValue), the third is the "text" that will be displayed in the list and the last parameter is the currently selected item.
Assuming your model is called MyTablesDB, then:
MyTablesDB db = new MyTablesDB();
For example:
public SelectList GetPullDown(object idSelected) {
myTablesDB myDB = new MyTablesDB();
return new SelectList(myDB.Products, "Product_ID", "Product_Name", idSelected);
}
Cheers,

Resources