This might be a first, but I actually stole this from myself off Stackoverflow. Posted it and thought it might be useful to share with the 1 live person who reads this blog and the 90 other bots… And I’m not sure about the 1 live person.
So here’s the situation, it’s late, you’ve got a strongly typed view that has a checkbox list, and you are desperate for an answer on how to handle it…. and now you’re scraping the bottom of the barrel. Well, good news is, I have the answer.
Let’s say you have a Book class that has a list of Categories. The Category class is simple, just has an id and name.
public class Book { public Int32 BookId { get; set; } public IList<Category> Categories { get; set; } } public class Category { public Int32 Id { get; set; } public String Name { get; set; } }
Now you could try and figure out a way to create a typed view using the Book class. You could also stomp on your left foot until it bleeds. Who am I to judge you for liking pain? (Sick f—) For those who don’t want to go through that nightmare, I have an alternative: Create two new classes, one to set the view and one to handle the post back.
public class ViewBookModel { public ViewBookModel(Book book, IList<Categories> categoryList) { BookId = book.Id; CategoryList = categoryList; } public Int32 BookId { get; private set; } IList<Categories> CategoryList { get; set; } }
First the class to set the view. As you can see, there is a book id that corresponds to a book object’s id (DUH) and the category list which you will set in the original action.
[AcceptVerbs(HttpVerbs.Get)] public ActionResult EditBook(Int32 bookId) { Book foundBook = Book.GetById(bookId); IList<Category> categoryList = Category.GetAll(); ViewBookModel model = new ViewBookModel(foundBook, categoryList); return View(model); }
And then your markup for the checkbox list will be something like this:
<% foreach(var category in Model.CategoryList) { %> <input type="checkbox" name="CategoryIds" value="<%= category.Id %>" /> <% } %>
Notice that the name for every input is CategoryIds. This is because this will be the name of the collection of ids on the model for posting:
public class ViewBookInModel { public String BookId { get; set; } public Int32[] CategoryIds { get; set; } }
And the action method would look like:
[AcceptVerbs(HttpVerbs.Post)] public ActionResult UpdateBook(ViewBookInModel book) { foreach(Int32 id in book.CategoryIds) { ... } }
And boom, problem solved. You can now use a strongly typed View with a checkbox list. Go forth and be fruitful.