views:

507

answers:

2

Consider this scenario:

class Book
{
    int id;
    List<Category> categories;
}

class Category
{
    int id;
    string name;
}

I have a strongly typed view for the class Book. When the librarian wants to edit the details of any Book, I want to display checkboxes with all possible categories. In case Book.categories contains a category, that check box will be checked.

The user can check and uncheck the boxes at will and then will click 'Submit'. I want that my controller function should be invoked with a parameter of type Book, with the new set of categories properly set.

How can this be done in ASP.NET MVC?

A: 

It can be done many ways.

I'd suggest keeping your views simple. A view should perform one particular function. You'd have a view to see details of the book, then a view to edit the book. This will make it easier to create a model which provides the information needed to store the book and its categories.


Update:

I agree checkboxes are the best way. For how to handle them on the trip back, see this question: http://stackoverflow.com/questions/220020/how-to-handle-checkboxes-in-asp-net-mvc-forms

Will
Will, yes, there are two views. One for each function:Add BookView List of BooksEdit Book (and choose what categories the book belongs to)View (Master List) List of CategoriesAdd a category to the master list.But.. how to do the mapping from categories to check boxes while editing the book?
+1  A: 

You might want to split this up into a couple of classes, one that is your book class, one for setting the view, and one for receiving the view's values. This may sound overdone but if nothing else it makes it so you aren't banging a square peg into a round hole. After all, if you just go with the Book class you have right now, you have to figure out how to make the view display everything you need (Say a bunch of check boxes for the categories... A list that your Book does not have completely) and then send it back to the controller still having to fit the same design as the Book class. To me that seems like in the long run a lot harder and maybe not possible without compromising the original book class design.

I would suggest something like this:

class ViewBookModel
{
  public ViewBookModel(Book book, IList<Categories> categoryList)
  {
    BookId = book.Id;
    BookName = book.BookName;
    CategoryList = categoryList;
  }

  public Int32 BookId { get; private set; }
  public String BookName { get; private set; }
  IList<Categories> CategoryList { get; set; }
}

And for posting back to the controller:

class ViewBookInModel
{
  public String BookId { get; set; }
  public String BookName { get; set }
  public Int32[] CategoryIds { get; set; }
}

And the markup would be something like:

<%
  foreach(var category in Model.CategoryList)
  {
%>
    <input type="checkbox" name="CategoryIds" value="<%= category.Id %>" />
<%
  }
%>

And the controller Method in:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UpdateBook(ViewBookInModel book)
Programmin Tool