My ultimate question is this – should a model binder populate all of the model, or only the bits that are being posted, leaving the controller to populate the rest?
For example, I am adding a product in my system and on the form i want the user to select which sites the new product will appear on. Therefore, in my model I want to populate a collection called “AllAvailableSites” to render the checkboxes for the user to choose from. I also need to populate the model with any chosen sites on a post in case the form does not validate, and I need to represent the form showing the initial selections. It would seem that I should let the model binder set the chosen sites on the model, and (once in the controller method) I set the “AllAvailableSites” on the model. Does that sound right? It seems more efficient to set everything in the model binder but someone is suggesting it is not quite right.
I am grateful for any advice; I have to say that all the MVC model binding help online seems to cite really simple examples, nothing complicated.
Also, do I really need a GET and a POST version of a method? Can’t they just take the same view model? Then I check in my model binder if it is a GET/POST, and populate all the model accordingly.
Your initial conclusion is sound. A model binder should only worry about creating an instance of a model and populating its properties with the values it has available to it from the action context (for example, post values), and then performing validation. Your controller is then responsible for populating any additional values required for the view, such as your list of available sites.
I’m not entirely sure what you mean about needing separate GET/POST methods. If you are saving or creating an instance of a model, you should be posting, so it would seem the GET part is irrelevant. Unless you mean something like:
Perhaps you are wondering if you can just combine them into one action and just figure out if they are viewing the edit form or posting the results of the edit form within the action. I would strongly encourage you not to do this. There is a variety of reasons, but let’s just keep it at that; don’t do it.