I am working on a fairly large MVC 3 application, and I’m running into an issue that doesn’t smell quite right to me. This question takes a little set up to understand, so here are the premises that I’m currently operating on:
- Views should be strongly typed (ViewBag/ViewData should be avoided)
- Because the views are strongly typed, view model objects should be created that encapsulate all the data the view needs to display
- When we have a need for drop down menus we should have two properties:
- A property in the model that stores the selected value of the drop down
- A
SelectListproperty in the view model that represents the items in the drop down
- The view itself always uses the
@Html.DropDownListFor()helper method - We are using Entity Framework 4, and letting it generate entity classes from our already designed database
- To avoid duplication and take advantage of LINQ, we are not creating our own separate business/model classes but adding to the partial classes generated by the entity framework
- These partial classes that we write are located in the business layer to make everything compile correctly
- Most model classes have a shared editor template that can be used in multiple views
Here’s where the trouble comes in. The shared editor template’s model type is set to the model class. This means that the partial view that makes up the editor template does not have access to the containing view model object where the list of drop down items is stored.
I was able to “solve” this by adding a SelectList property directly to the model class in the business layer instead of keeping it in the view model. But the SelectList class is specific to MVC, which in turn means that my business layer has a dependcy on MVC. That doesn’t seem right to me because the BL should be agnostic to the UI.
Has anyone else run into this issue? How should I solve this? It’s also possible that one of my premises are wrong.
Well, we ended up taking the simple way out. In the business layer we just changed the type to plain old
Object. I figured that, regardless of the presentation layer, it will need some sort of list to contain the options available.I know this isn’t super clean as per @Darin and @Jakub, but I don’t see our end result being any different this way except that we’ve avoided having to write and/or set up a whole bunch of mappings between objects.