Value cannot be null. Parameter name: source in MVC listbox - asp.net-mvc-3

I have found plenty of posts about this, but none of them are solving my issue. My code right now:
#Html.ListBox("SelectedNewsletter", Model.Newsletters)
and
public MultiSelectList Newsletters
{
get
{
return new MultiSelectList(
new[]
{
// TODO: Fetch from your repository
new { Id = 1, Name = "item 1" },
new { Id = 2, Name = "item 2" },
new { Id = 3, Name = "item 3" },
},
"Id",
"Name"
);
// return new MultiSelectList(PromoNewsletter.All, "IdString", "Display");
}
}
As far as I can see, it's all hard coded now, and it still gives the same error. I want to do a ListboxFor, but I am trying to just get a listbox to work. I have replaced my int id with a string representation, based on advice I found elsewhere, but now I don't see what else I can do. It just plain is not working, even with all hard coded values and not binding to a property on my ViewModel. Where am I going wrong ?

The error is occurring because you have a property in the Model or ViewData/ViewBag with the name SelectedNewsletter.
Give a different name for the ListBox if you can't rename that property.
UPDATE:
After little more experimenting I figured out that the problem is you may be setting an integer value to the SelectedNewsletter that is somewhere in the ViewData/ViewBag or Model.
You can set the values that has to be selected in the ListBox as a string or array of strings to the SelectedNewsletter.
i.e SelectedNewsletter = "1";
or
SelectedNewsletter = new[] { "1", "3" };
You can also use strongly typed helper to make things easy,
#Html.ListBoxFor(m => m.SelectedNewsletter, Model.NewsLetters);

Related

How to Populate ListBoxFor in Mvc3?

I have a list of type stored procedure which have an ID and a Name as data in it.
i have property of int type in model and a list of same stored procedure.
now i want to bind this information into ListBoxFor
in view i have written this
#Html.ListBoxFor(x => x.HobbyId, new MultiSelectList(Model.listHobby, "pkHobbyId", "Hobby"))
but i am getting an error
The parameter 'expression' must evaluate to an IEnumerable when multiple selection is allowed.
Please Help how to bind.
try that
#Html.ListBoxFor(x => x.HobbyId, Model.listHobby.Select(f => new SelectListItem { Text = f.Hobby, Value = f.pkHobbyId.ToString() }), new { Multiple = "multiple" })
listHobby is iEnumerable list on my sample
sorry if i mislead you, rushed to answer but you cannot get the result of the multiselect listbox into a guid or int variable (whatever type is your HoobyId is) you should have an array to grab the result like
public string[] SelectedHobbyIds { get; set; }
so there must be something wrong with your View Models so its better that u would post your view models to be checked
# Chhatrapati Sharma,
In your controller, try this,
ViewData['anyName'] = new SelectList {
Text = , // text from ur function
Value = , // Value from function
Selected = // if required
}
and in view, bind the viewdata like,
<#Html.ListBox("docImages", ((IEnumerable<SelectListItem>)ViewData["anyName"]))
For testing, try a sample selectlist item as follows,
ViewData['anyName'] = new List<SelectListItem>{
new SelectListItem {Text = "First", Value = "0"},
new SelectListItem {Text = "Second"), Value = "1"},
new SelectListItem {Text = "Third", Value = "2"}
};
If this sample works, then check your function "_supp.listDocImages()" and make sure it return IList
#Html.ListBoxFor(x => x.HobbyId, Model.listHobby.Select(f => new SelectListItem { Text = f.Hobby, Value = f.pkHobbyId.ToString() }), new { Multiple = "multiple" })
HobbyId in expression must be ienumerable because you set multi select

Trying to use [Description] data annotation attribute with existing code

SLIGHT UPDATE BELOW
I am trying to use the [Description] data annotation attribute with enums in order to display a friendly name. I've searched around a lot and cannot get anything implemented. Right now I have code that will display an enum as a string (using an extension), but I am not liking ThisIsAnEnum as an enum name (which is spaced out by the string extension) and it prohibits me from having longer names (which I need to maintain) such as for a radio button item. My goal is to have longer descriptions for radio button items without having to write really long enums. An extension/helper will probably be the right way to go, but I need to "fit" it into the code I am using, which is where I failed using the many examples out there.
The code I am using is generic, in that depending upon some logic either a radio button list, check box list, drop down list, select list or regular text boxes are displayed. For multi-item lists enum's are used, and the enum name is what is displayed (after using the string extension).
Here is the particular code that displays the enum:
public static IEnumerable<SelectListItem> GetItemsFromEnum<T>
(T selectedValue = default(T)) where T : struct
{
return from name in Enum.GetNames(typeof(T))
let enumValue = Convert.ToString((T)Enum.Parse(typeof(T), name, true))
select new SelectListItem
{
Text = name.ProperCase(),
Value = enumValue,
Selected = enumValue.Equals(selectedValue)
};
}
ProperCase is the class that changes the enum to something readable.
I found something that almost worked:
public static string GetEnumDescription<TEnum>(TEnum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if ((attributes != null) && (attributes.Length > 0))
return attributes[0].Description;
else
return value.ToString();
}
in which case I changed code from Text = name.ProperCase(), to Text = name.GetEnumDescription(...) but if I put value in the parenthesis I get a "does not exist in the current context" message (which I tried fixing but just made the problem worse). If I leave it blank I get the "No overload for ... takes 0 arguments" (again, understandable - but I don't know how to fix). And if I put name in the parenthesis the code compiles but upon viewing the page I get the "Object reference not set..." error on this line:
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes
(typeof(DescriptionAttribute), false);
I've spent a lot of time on this and know that my stumbling block is the
Text = name.ProperCase(),
code. Any ideas/help? Thanks in advance.
UPDATE:
If I do:
Text = GetEnumDescription(selectedValue),
I actually DO get the [Description] text, however, it just displays for the first enum. So, if I have 5 enums all with different [Description]'s the code just repeats the [Description] for the first enum 5 times instead of displaying differently for each. I hope that makes sense and gets to narrow down the problem.
I'd recommend you the Display attribute:
public static IEnumerable<SelectListItem> GetItemsFromEnum<T>(T selectedValue = default(T)) where T : struct
{
return
from name in Enum.GetNames(typeof(T))
let enumValue = Convert.ToString((T)Enum.Parse(typeof(T), name, true))
select new SelectListItem
{
Text = GetEnumDescription(name, typeof(T)),
Value = enumValue,
Selected = name == selectedValue.ToString()
};
}
public static string GetEnumDescription(string value, Type enumType)
{
var fi = enumType.GetField(value.ToString());
var display = fi
.GetCustomAttributes(typeof(DisplayAttribute), false)
.OfType<DisplayAttribute>()
.FirstOrDefault();
if (display != null)
{
return display.Name;
}
return value;
}
and then you could have:
public enum Foo
{
[Display(Name = "value 1")]
Value1,
Value2,
[Display(Name = "value 3")]
Value3
}
And now you could have:
var foo = Foo.Value2;
var values = GetItemsFromEnum(foo);
Also notice that I have modified the Selected clause in the LINQ expression as yours is not correct.
This being said, personally I would recommend you staying away from enums on your view models as they don't play nicely with what's built-in ASP.NET MVC and you will have to reinvent most of the things.

How to get DropDownList text from selected value via Linq

I am quite new to MVC3, and developing a DropDownListFor which i need to get both value and text for display result purpose. Any ideas on this issue? Thanks!
In my controller:
ViewBag.vehicleSizes = totalGreenCalculator.GreenCalculator.getVehicleFuelEfficiency();
In my Model:
//Datatype: fuelEfficiency = double, vehicleSizes = string
public IEnumerable<SelectListItem> getVehicleFuelEfficiency()
{
var size = new[] {new vehicleSize {fuelEfficiency = 0.0, vehicleSizes = "Choose your vehicle size"},
//and so on
};
return size.Select(a => new SelectListItem() { Text = a.vehicleSizes, Value = a.fuelEfficiency.ToString() });
}
View:
#Html.DropDownListFor(model => model.GreenCalculator.vehicleList[i].fuelEfficiency, (IEnumerable<SelectListItem>)ViewBag.vehicleSizes)
You can recieve IDictionary on controller. Dropdownlist name must match the name of the dictionary.
Your code looks fine. It will generate the dropdownlist from the given values. But it won't preselect the default option. That's because in the first argument you have used a complex expression. If you wanted to preselect some item you could do this:
#Html.DropDownListFor(
x => x.GreenCalculator.vehicleList[i].fuelEfficiency,
new SelectList(
(IEnumerable<SelectListItem>)ViewBag.vehicleSizes,
"Value",
"Text",
Model.GreenCalculator.vehicleList[i].fuelEfficiency
)
)

MVC3 Drop Down list not selectng selected item

I have a C#.Net MVC3 web app. I am using Drop Down lists all over the place and having success. However, there are two that I am having trouble with. The only difference is that I am creating the SelectLists on the fly in the code rather than using Lookup tables. I use lookup tables for all the other Drop Downs. When I QuickWatch the SelectLists in the code, the correct Item has the Selected property value set to true. However, when the page loads, the item with the Selected property is not displayed. The first item is. Any ideas? This is one of those werid ones. I've tried both ways below. In both cases, the ViewBag.DateToYear and the SelectList DateToYear have the right values and 'Selected' properties set
1)
//Controller
IList<string> dateToYear = new List<string>();
for (int i = 0; i < numberYears; i++)
{
dateToYear.Add(DateTime.Now.AddYears(i).Year.ToString());
}
ViewBag.DateToYear = new SelectList(dateToYear,"2014")
//View
#Html.DropDownList("DateFromYear", (SelectList)ViewBag.DateToYear )
2)
//Controller
SAME as above
//View
List<SelectListItem> DateToYear = new List<SelectListItem>();
foreach (var m in ViewBag.DateToYear)
{
DateToYear.Add(new SelectListItem { Selected = #m.Selected, Value = #m.Text, Text = #m.Text });
}
#Html.DropDownList("DateFromYear", DateToYear)
The problem is, SelectList works as designed. The bug is in the design. You may set the Selected Property in SelctedItem, but this will completely be ignored, if you traverse the list with the GetEnumerator() ( or if Mvc does that for you). Mvc will create new SelectfListItems instead.
You have to use the SelectList ctor with the SelectListItem[], the Text-Name, the Value-Name and the SelectedValue. Be aware to pass as SelectedValue the VALUE of SelectListItem, which you want to be selected, not the SelectListItem itself! Example:
Why not just do in the controller ?
Pseudo code :
//controller
ViewBag.DateToYear = new SelectList(new[]
{
new SelectListItem { Text = "10", Value = "10" },
new SelectListItem { Text = "15", Value = "15" }
new SelectListItem { Text = "25", Value = "25" },
new SelectListItem { Text = "50", Value = "50" },
new SelectListItem { Text = "100", Value = "100" },
new SelectListItem { Text = "1000", Value = "1000" },
}, "SomeText", "Value", "15");
The second option should be selected.
Not sure if this is the case, but I had some problem with dropdownboxes not getting selected a few days ago.
My problem was: I have a #model.Options and I created a #html.dropdownlist("Options", #model.Options, [...]). However, because they had the same name it somehow conflicted. When I used #html.dropdownlist("anythingElse", #model.Options, [...]) it worked fine.
When I QuickWatched return View(model) the selected options seemed to be set correct too, so it took a while to figure that out. Maybe you have the same problem?
Same thing was happening to me too, make sure you do not give same ID as the property name you gave on your Model. That is how I solved this issue...

MVC 1.0 DropDownList static data select not working

I'm new to MVC and C#. I'm trying to get a static list to work with a DropDownList control such that the selected value rendered is set by the current Model value from the DB.
In the controller, I have:
ViewData["GenderList"] = new SelectList(new[] { "Female", "Male", "Unknown" }, donor.Gender);
In the view:
Gender:<%=Html.DropDownList("Gender", (IEnumerable<SelectListItem>)ViewData["GenderList"]) %>
In the debugger, donor.Gender is "Male", but "Female" gets rendered in the view.
I've read a number of posts related to select, but I've not found one that applies to a static list (e.g., where there's no "value" and "name" to play with). I'm probably doing something stupid...
This may sound like a stupid question but is donor.Gender a string value, and does it match case with the hard-coded values you've used EG 'Male'?
The reason I ask is because this;
ViewData["GenderList"] = new SelectList(new[] { "Female", "Male", "Unknown" }, "Male");
works a treat, but this;
ViewData["GenderList"] = new SelectList(new[] { "Female", "Male", "Unknown" }, "male");
returns your result
Thanks to Si, here's the final solution I came up with:
In the controller, this:
ViewData["GenderList"] = repo.GetGenders(donor.Gender);
In the DonorRepository, this:
public SelectList GetGenders(string selected) {
SelectList genders = new SelectList(new[] { "Female ", "Male ", "Unknown" }, (selected == null ? null : selected.ToString().PadRight(7).ToCharArray()));
return (genders);
}
Then in the View, just this:
<%= Html.DropDownList("Gender", (IEnumerable<SelectListItem>)ViewData["GenderList"], "--Select--")%>
NOTE: PadRight(7) equals the Donor.Gender DB specification of Char(7). Also note the SelectList constant space padding of "1234567" for each selectlistitem.

Resources