MVC3 Razor (Drop Down List) - asp.net-mvc-3

I'm new towards MVC3 Razor. Currently, I'm facing this error "Object reference not set to an instance of an object.", which I have no idea what is this about.
In Model
public List<SelectListItem> CatList { get; set; }
[Display(Name = "Category")]
public string CatID { get; set; }
In Controller
public ActionResult DisplayCategory()
{
var model = new CatModel();
model.CatList = GetCat();
return View(model);
}
private List<SelectListItem> GetCat()
{
List<SelectListItem> itemList = new List<SelectListItem>();
itemList.Add(new SelectListItem { Text = "1", Value = "1" });
itemList.Add(new SelectListItem { Text = "2", Value = "2" });
return itemList;
}
In CSHTML
#using (Html.BeginForm())
{
<table>
<tr>
<td>#Html.LabelFor(c => c.CatID)</td>
<td>#Html.DropDownListFor(c => c.CatID, Model.CatList)</td>
</tr>
</table>
}
Thanks for any help.

I suspect that you have a POST action in which you forgot to reassign the CatList property of your view model so you are getting the NRE when you submit the form, not when the form is initially rendered:
public ActionResult DisplayCategory()
{
var model = new CatModel();
model.CatList = GetCat();
return View(model);
}
[HttpPost]
public ActionResult Index(CatModel model)
{
// some processing ...
// since we return the same view we need to populate the CatList property
// the same way we did in the GET action
model.CatList = GetCat();
return View(model);
}
private List<SelectListItem> GetCat()
{
List<SelectListItem> itemList = new List<SelectListItem>();
itemList.Add(new SelectListItem { Text = "1", Value = "1" });
itemList.Add(new SelectListItem { Text = "2", Value = "2" });
return itemList;
}

Related

Setting the default value of multiple dropdown lists on page load

I have a model,
public class Customer
{
public string Name { get; set;}
public string CountryCode { get; set;}
}
In the controller
var model = new List<Customer>
{
new Customer { Name = "foo", CountryCode = "US"},
new Customer { Name = "bar", CountryCode = "UK",
};
return PartialView("_Edit", model);
An extension method for displaying all countries:-
public class CountryList
{
public static IEnumerable<SelectListItem> CountrySelectList
{
get
{
var list = new List<SelectListItem>()
{
new SelectListItem { Value = "US", Text="US" },
new SelectListItem { Value = "UK", Text="UK" },
};
return list;
}
}
}
In the PartialView
#model List<Customer>
#Html.DropDownListFor(model => model[i].CountryCode, CountryList.CountrySelectList, "Select Country Type")
But the drop down doesn't select each customer's country code? Any thoughts?
PS: It is using model[i] => which is of type Customer, for simplicity i had removed the forloop before rendering the html tags.
#using(Html.BeginForm())
{
for(int i = 0; i < Model.Count(); i++)
{
#Html.TextBoxFor(model => model[i].Name)
#Html.DropDownListFor..........
}
}
Because your CoutryList helper does returns a list of SelectListItems that all have Selected property set to False (which is default).
I would rewrite your helper method as follows:
public static IEnumerable<SelectListItem> CountrySelectList(string selectedCountryCode)
{
get
{
var list = new List<SelectListItem>()
{
new SelectListItem { Value = "US", Text="US" },
new SelectListItem { Value = "UK", Text="UK" },
};
var selectedListItem = list.FirstOrDefault(t=>t.Value== selectedCountryCode);
if(selectedListItem!=null)
selectedListItem.Selected=true;
return list;
}
}
In view:
#Html.DropDownListFor(model => model[i].Customer, CountryList.CountrySelectList(model[i].Customer.CountryCode), "Select Country Type")

SelectList in MVC3

I have a MVC3 page that has to dropdownList contains Sex(male,female) and Role(admin,Operator), in RegisterViewModel I have done like this :
public List<SelectListItem> SelectedItemForSex { get; set; }
public List<SelectListItem> SelectedItemForRole { get; set; }
public string SearchText { get; set; }
public string SelectedValue { get; set; }
//public string SelectedValueForRole { get; set; }
public static RegisterViewModel Get()
{
var model = new RegisterViewModel { SelectedItemForSex = new List<SelectListItem>() };
model.SelectedItemForSex.Add(new SelectListItem() { Text = "Male", Value = "1" });
model.SelectedItemForSex.Add(new SelectListItem() { Text = "Femle", Value = "2" });
model.SelectedItemForRole.Add(new SelectListItem() {Text = "Administrator", Value = "1"});
model.SelectedItemForRole.Add(new SelectListItem() {Text = "Operator", Value = "2"});
return model;
}
and in get action of Register I have this code :
public ActionResult Create()
{
var model = RegisterViewModel.Get();
return View(model);
}
and also in razor :
<div>
#Html.LabelFor(register => register.Sex)
#Html.DropDownListFor(register => register.SelectedValue, new SelectList(Model.SelectedItemForSex, "Value", "Text"))
</div>
<div>
#Html.LabelFor(register => register.Role)
#Html.DropDownListFor(register => register.SelectedValue, new SelectList(Model.SelectedItemForRole, "Value", "Text"))
</div>
<div>
I know I have Not initialize selectedListItem for Administrator and operator , I wanna to send all of this 4 value via Get() method, How can I do this ??

Error when trying to post MVC form with Dropdown list in it

I looked at similar posts but nothing working for my case.
I have a form which loads fine and I see the categories dropdown with all categories in it.
The problem is when I try to post the form.
I get this error:
The ViewData item that has the key 'Category' is of type 'System.String' but must be of type 'IEnumerable'.
#Html.DropDownList("Category", Model.Categories) <-- red color
Here is my view:
#using (Html.BeginForm("Save", "Album", FormMethod.Post, new { id = "frmNewAlbum" }))
{
#Html.DropDownList("Category", Model.Categories)
}
Here is my model:
public class AlbumModel
{
public string Title { get; set; }
public string Category { get; set; }
public List<SelectListItem> Categories { get; set; } <-- holds categories
}
This is the controller actions to view the page:
[HttpGet]
public ActionResult Save()
{
var model = new AlbumModel();
var categories = new List<SelectListItem>() { new SelectListItem() { Text = "-- pick --" } };
categories.AddRange(svc.GetAll().Select(x => new SelectListItem() { Text = x.Name, Value = x.Name }));
model.Categories = categories;
return View(model);
}
Action that receives the post:
[HttpPost]
public ActionResult Save(AlbumModel model)
{
var album = new AlbumDoc()
{
Category = model.Category,
Title = model.Title,
};
svc.SaveAlbum(album);
return View(model);
}
In your POST action you seem to be redisplaying the same view but you are not populating the Categories property on your view model which will contain the dropdown list values. And by the way I would recommend you using strongly typed helper. So:
public class AlbumController: Controller
{
[HttpGet]
public ActionResult Save()
{
var model = new AlbumModel();
model.Categories = GetCategories();
return View(model);
}
[HttpPost]
public ActionResult Save(AlbumModel model)
{
var album = new AlbumDoc()
{
Category = model.Category,
Title = model.Title,
};
svc.SaveAlbum(album);
model.Categories = GetCategories();
return View(model);
}
private IList<SelectListItem> GetCategories()
{
return svc
.GetAll()
.ToList()
.Select(x => new SelectListItem
{
Text = x.Name,
Value = x.Name
});
}
}
and in your view:
#model AlbumModel
...
#using (Html.BeginForm("Save", "Album", FormMethod.Post, new { id = "frmNewAlbum" }))
{
#Html.DropDownListFor(
x => x.Category,
Model.Categories,
-- pick --
)
}

DropDownListFor - Model Binding

My first MVC project and have ran into an issue which I hope someone can assist with.
Basically I have a DropDownListFor object which I want to populate with a list of available times for the user to pick from and store the selected item in an attribute for later consumption.
The below is producing a null value error so I'm missing something obvious, any help would be appreciated.
Here's what I have:
Controller:
private MyModelObject m_model = new MyModelObject();
public ActionResult Index()
{
var AvailTimes = new SelectList(new[]
{
new {Value="00:00",Text="12:00 AM"},
new {Value="00:30",Text="12:30 AM"},
new {Value="01:00",Text="1:00 AM"},
new {Value="22:30",Text="10:30 PM"},
new {Value="23:00",Text="11:00 PM"},
new {Value="23:30",Text="11:30 PM"},
});
return View(m_model);
}
Model:
public class MyModelObject
{
public string StartTime { get; set; }
public IEnumerable<SelectList> AvailTimes { get; set; }
}
View:
#Html.DropDownListFor(model => model.StartTime,
new SelectList(model.AvailTimes, "Value", "Text"))
Don't make your model a private variable to the controller. Each time a request is sent a new controller instance will be created so don't think that you will be able to reuse it between actions. Also you don't seem to be doing anything useful with the AvailTimes local variable that you declared in your action and it is subject to a fast garbage collection. Also your model is incorrect. The AvailTimes property must be an IEnumerable<SelectListItem> and not IEnumerable<SelectList>.
Let's start by fixing the view model first:
public class MyModelObject
{
public string StartTime { get; set; }
public IEnumerable<SelectListItem> AvailTimes { get; set; }
}
then the controller action which will feed the view model:
public ActionResult Index()
{
var model = MyModelObject
{
AvailTimes = new[]
{
new SelectListItem { Value = "00:00", Text = "12:00 AM" },
new SelectListItem { Value = "00:30", Text = "12:30 AM" },
new SelectListItem { Value = "01:00", Text = "1:00 AM" },
new SelectListItem { Value = "22:30", Text = "10:30 PM" },
new SelectListItem { Value = "23:00", Text = "11:00 PM" },
new SelectListItem { Value = "23:30", Text = "11:30 PM" },
}
};
return View(model);
}
and finally the strongly typed view:
#model MyModelObject
#Html.DropDownListFor(x => x.StartTime, Model.AvailTimes)
You also have the possibility to assign those available hours in your view model directly:
public class MyModelObject
{
public string StartTime { get; set; }
public IEnumerable<SelectListItem> AvailTimes
{
get
{
return new[]
{
new SelectListItem { Value = "00:00", Text = "12:00 AM" },
new SelectListItem { Value = "00:30", Text = "12:30 AM" },
new SelectListItem { Value = "01:00", Text = "1:00 AM" },
new SelectListItem { Value = "22:30", Text = "10:30 PM" },
new SelectListItem { Value = "23:00", Text = "11:00 PM" },
new SelectListItem { Value = "23:30", Text = "11:30 PM" },
};
}
}
}
Now your controller action could become:
public ActionResult Index()
{
var model = MyModelObject();
return View(model);
}
and the view obviously stays unchanged.
The value of Model.AvailTimes is never assigned, therefore is null by default.

asp.net mvc 3 Dropdownlist issues, must be of type 'IEnumerable<SelectListItem>'?

I have the following error when I click save:
the ViewData item that has the key 'SelectedCategoryId' is of type 'System.Int32' but must be of type 'IEnumerable'?
my controller:
public ActionResult IndexTwee()
{
var listCategories = new List<SelectListItem>();
listCategories.Add(new SelectListItem() {Text="foo",Value="1" });
listCategories.Add(new SelectListItem() { Text = "bar", Value = "2" });
MyViewModelTwee model = new MyViewModelTwee() { };
model.Categories = listCategories;
model.SelectedCategoryId = 2;
return View(model);
}
[HttpPost]
public ActionResult IndexTwee(MyViewModelTwee Model)
{
return View(Model);
}
my model:
public class MyViewModelTwee
{
public int SelectedCategoryId { get; set; }
public IEnumerable<SelectListItem> Categories { get; set; }
}
my view:
#model mvc3DropDown.Models.MyViewModelTwee
#using (Html.BeginForm())
{
#Html.DropDownListFor(
x => x.SelectedCategoryId,
Model.Categories
)
<button>Save</button>
}
Don't forget to rebind the list in your POST action:
[HttpPost]
public ActionResult Index(MyViewModelTwee Model)
{
var listCategories = new List<SelectListItem>();
listCategories.Add(new SelectListItem() { Text = "foo", Value = "1" });
listCategories.Add(new SelectListItem() { Text = "bar", Value = "2" });
Model.Categories = listCategories;
return View(Model);
}
Remember that only the selected value is sent when you submit the html <form>. The other values are lost so you need to refetch them from wherever you fetched them in the GET action. Of course you will externalize this code into a repository layer so that your code now looks like this:
public ActionResult IndexTwee()
{
var model = new MyViewModelTwee
{
SelectedCategoryId = 2,
Categories = _repository.GetCategories()
};
return View(model);
}
[HttpPost]
public ActionResult IndexTwee(MyViewModelTwee Model)
{
Model.Categories = _repository.GetCategories();
return View(Model);
}

Resources