MVC Controller design - asp.net-mvc

I am working on MVC project and on Admin side I have to create CRUD forms for Products, Category, SubCategory.
Which of these approach will be better:
Create one AdminController and have CRUD Action methods for Products, Category, SubCategory.
Create Separate Controllers for Products, Category, SubCategory which have individual CRUD Action Methods?
Thanks for help

As the others have said, is better to have separate Controllers. I would alse recommend to put them in an Admin Area so you have the functionality "separated" from the main site.

It's always best to keep your controllers as light as possible so I'd go for separate controllers for each. You might want to take a look at the MVC Controller Scaffolding feature which is now more easily available in the MVC 3 Tools Update. It's perfect for this kind of "basic" CRUD work.

i would opt for having every functionality with Products in the products controller etc. mainly because of the Single responsibility principle
in MVC3 you can automatically generate controllers with CRUD methods / screens if you use the add controller wizard.
example: http://msdn.microsoft.com/en-us/data/gg685467
imo the controller should only be a thin layer talking to a business service layer who's handling all the business logic. For example the products you could create a ProductService that will handle your business logic.

Usually, it's a good thing to follow REST principles.
The idea is quite simple - every "resource" should map to controller (approach #2).
However, I think it's better to "cut along natural joints".
With that I mean - sometimes decomposition (dividing into more controllers) just for sake of it leads to unnecessary complexity. Controllers should appear accordingly to Your use cases.
Start with one (which appears as most important) and slice next when current one exceeds ~100 loc.

Related

How to simplify MVC pattern for a demo purpose?

I have to set up a Asp.net demo using MVC 4 in a web application in order to help decision for a product that currently don't use this pattern. The model, view and controller should be simple, I just have two or three entities and a few pages.
I suppose I don't have to implement the whole infrastructure with services, repositories, etc. So how could I simplify the MVC components without loosing those advantages?
The MVC components aren't related to the data access strategy which you can use. To put together a quick demo (or a simple application) you can leave the data access in the same project but eventually split that out etc.
You can use something like AutoMapper to map from your entities to your view models if you want to put that level of abstraction in. You can also use EntityFramework contexts in the controllers to avoid additional levels of abstraction and only put in a simple interface/abstraction into one controller to show unit test ability.
Small examples of different patterns which could be used in the application is probably the way to go for the demo/presentation and not worry too much about putting them in all over the place. Remember the presentation and the delivery of information is as important, it not more, than the demo code itself.

Does this approach to fat model/skinny controller take it too far?

I am afraid that I might be getting lazy.
I am developing a ruby on rails application involving about 8 models relating to two types of users: physicians and patients. Most of the logic is inside the models allowing my controller actions to be very short and concise. Plus, it makes the testing fairly straightforward.
I currently envision at least two controllers and the tests that I am writing lead me to believe that most of my user-facing features can be handled by these two controllers. Sure, I can break this into more sensible compartments-like tests for a patients-controller, physicians-controller, patient-medications controller, patient-lab-results-controller and so on. But it seems to me that the only advantage here is more discreet organization.
On to the question, asides from compartmentalization, what are the reasons NOT to use as few controllers as possible, pack them with lots of actions [disadvantage], but keep the actions skinny [advantage]? Or...to take it to an extreme: Why not with MVC, have a bunch of fat models, and one skinny [albeit long] controller rather than a patient controller/model/views+tests for EACH, physician controller/model/views+tests for EACH, etc?
There's organization, as making everything inside a single controller is possible, it's going to be harder to understand and change. Instead of being able to open a file in your editor and finding the action you're looking for right away, you would be scrolling down the file to find what you're looking for.
This also leads to the God object pattern where everything happens inside a single object that's responsible for everything and everyone working at the project will be changing this same object, leading to an eternal merge hell.
And, on Rails itself, there's the RESTful-ness of the framework. Rails embraces the idea of being RESTful and one of the pillars of this idea are the resources and they can only be easily organized in separate controllers. If you try to place two different resources at the same controller you'll probably end up with crazy routes or crazy controller logic to find out which model is being represented.
If you think your controllers have a lot of repeated code, you can DRY them out using some metaprogramming magic or conventions, but it's really better to have them separated, not only for organization but also to simplify your own future maintenance.
If there's a lot of common controller logic, you might consider abstracting it out into a plugin or module that you can mix in when needed. Or the controllers could inherit from a common base controller (much as all controllers inherit by default from ApplicationController, rather than ActionController::Base).
I would advise against having one gigantic controller; a controller should manage the set of actions which pertain to a single type of resource (or the closest analog possible). This idea is even stronger if you are trying to create a RESTful design, in which each controller typically has nothing other than the basic seven actions (index, show, new, create, edit, update, destroy).
So if you want to have URLs like /patients/52394802/lab_results, I think it makes complete sense to have a LabResultsController. If these controllers are lightweight, awesome. I'm of the opinion that their existence is still justified. This shouldn't stop you from trying to make your code DRY; rather, I would simply try to abstract away the common functionality differently.
That's an impossible question to answer. Controllers are about routes and user interactions and views not business logic. Have as many controllers and actions that it makes sense to have for your links and views!
If your business logic is all in your models then it's simple enough. The main difficulty with logic in controllers is that you can't re-use the logic.
Nothing much more to say really. It's up to you to do what makes sense in your app. e.g. have a search controller to search for stuff rather than adding a search action to your existing controllers is not really about anything more than separation and clarity

When should you create separate controllers with ASP.NET MVC?

I'm starting to learn ASP.NET MVC. I understand the concept of controllers, models, and views. Yet now that I'm starting to design my first site I'm a little lost as to what controllers I should be creating. Do most model objects have a corresponding controller? Or are there other considerations I should be making when grouping action methods into seperate controllers?
Controllers logically separate small areas of functionality (Not to be confused with Areas in MVC which separate larger functional sections).
Do you have User Account Management for stuff like CreateAccount, ChangePassword? That's a UserAccountController.
Do you have functionality that allows people to create, view, delete Forum Postings? That's your ForumController.
Do you have functionality that allows people to manage their Preferences? That's your PreferencesController.
It's not so much 1 Controller per Model, it's 1 Controller per logical section in your app (which often indeed is one Model class). Some non-trivial MVC Sites work fine with only one controller, while my last project had eight of them.
In my limited experience with MVC so far, most of my controllers correspond to the model objects. I would also feel that you would create controllers for specific functionality within your site, like uploading files, etc.

What is the advantage of using multiple Controller classes in ASP.NET MVC?

I'm just learning the basics of ASP.NET MVC and am wondering what the benefit is in breaking up website logic amongst multiple controllers versus just having a single Controller class that runs the whole website, besides simply organizing code better. (In my opinion, just the latter benefit should not be enough to affect the end user via the url due to separation of concerns: the implementation details of the site should not be being reflected in the urls the site uses, no?)
Some examples on Controllers I've been reading show different controllers for things like "Product" or "User" or "Post". These clearly correspond to classes of objects followed by actions that can be taken on those (looking at the url right now I see stackoverflow.com/questions/ask).
Is there an advantage of splitting up the website into separate controller classes like QuestionsController versus just having a single default controller and handling these actions within it, for example stackoverflow.com/ask-question (besides it looking slightly uglier).
I ask because I'm not particularly interested in making my website RESTful (I looked into it a bit but deemed it too limiting) and instead favour query string parameters to pass information about a request. Therefore, the concept of splitting a url up into controller and action doesn't make sense to me, since the action and class information will be represented in the query string.
Finally, I much prefer the simpler look of urls like www.mysite.com/about versus www.mysite.com/home/about (what does that even mean?), again leading me to wonder what the point of multiple controllers really is.
You can achieve practically any url scheme you desire with ASP.Net MVC Routing. What controllers you have and where your actions live has nothing to do with your urls. Only routing defines your url's. Therefore, there is no reason whatsoever to sacrifice code clarity and organization for the sake of a particular url scheme.
Furthermore, in most ASP.Net MVC applications I've seen, the controllers are already unwieldy, and combining them all into a single controller would increase the disorganization exponentially.
Even small sites have a handful or two of controllers. Significant sites have dozens, very large sites could have hundreds. Do you really think it is in any way at all feasible to combine dozens of controllers into a single one?
The beauty of ASP.NET MVC comes from the fact that it makes separation of concerns so simple. Unlike ASP.NET Webforms where each page is essentially the View and the Controller, in ASP.NET MVC you can abstract your model logic into separate concerns or 'feature groups'. It makes sense to have a ProductsController that handles everything to do with Products because then you can isolate each set of related functionality in your application into uniform groups that are independently testable and maintainable.
Having a DoEverythingController fundamentally defeats the reasoning behind MVC because it clumps all of the model logic together into one giant spaghetti bowl of code, as opposed to keeping it neat and organized. Furthermore, having a Controller that does everything is not especially object-oriented and resembles a more procedural approach to development like many (older) PHP websites which have some central "functions.php" or similar that does everything. It's messy and disorganized.
In regards to your final point, the routing engine in MVC allows you to construct your routes to given controller actions however you want. The About() action of ControllerX and the Contact() action of ControllerY can both have root URLs like /about and /contact so long as you define the routes accordingly.
Edit (too long for comment)
Generally speaking, the controller classes will be pretty thin as far as code and logic is concerned. Well designed controllers will often hand off more complex operations like retrieving data from the data store to some kind of service so that the surface area for failure remains small. Despite the 'thinness' of most controllers, the larger your site is, the more operations will need to occur and the bulkier your universal controller is going to become. Even in non-MVC scenarios, huge code files suck to maintain and update (like "functions.php" above, for example).
If the site you're developing with MVC is small and limited to only a few more-or-less static pages, then using a single controller for all of them might be a reasonable approach, but if you are constructing a scalable application that will change over time it would be truly defeatist to forgo the use of multiple controllers.
Is like to have all files in the same directory or keep files separated in different folders.
Keeping the application organized in separate controller help in many cases:
1) memory performances
Different from Java Servlet where the controller is shared betwen many request, in asp net mvc the controller is created for each request.
Each time the user make a request, the application need to create the controller.
Think at performances comparison betwen create in memory an instance of a fatcontroller of 100k VS one instance of a light controller of 1k.
2) OO benefit
Controllers are classes. Each time you create a new controller you extend the base controller.
In a complex application you can create yours own controrres (can be more than one) and extend the more appropriated.
For example you can create a controller for "products" and extend from it to create a controller for "vegetables products" and so on..
3) Security.
Suppose that in your application you have a page that execute the CRUD actions on a given item of your db:
- display
- edit
- update
- delete
You want to make this page reserved for registered user only.
If you put all this method in one separate controller you can put the annotation [Authorize] on the controller and by default all the methods inside the controller will be protected.
If you put all the application in one fat controller you have to be careful to place the [Authorize] on each method (what happe if you forgive to put the annotation on the delete method?)
[Authorize]
public class ProductController
public ActionResult Index(String id) {
...
}
public ActionResult Update(String id) {
...
}
public ActionResult Delete(String id) {
...
}
4) Security again.
Suppose you write a classic CRUD (Create Read Update Delete).
Now you want to delete the whole CRUD.
If you keep code separate in different controller you simply delete the controller that belog the CRUD.
If you keep all together in a fatcontroller you have to search for the methods that belog to the CRUD in the whole code.
Again: what hapen if you forget to delete the Delete method?
5) practicality
If you put all together you will have methods like this:
product_edit
product_delete
product_rate
product_create
category_edit
category_delete
category_create
If you organize code in separate controller you will have
product
edit
delte
create
rate
category
edit
delete
create
This is good for many reason: want to modify product in item? simply refactor and rename the productController in itemController.
chaiguy
i think this topic has the potential to illustrate (from the answers) the true benefits of using the controllers to do their own 'lightweight' tasks. one of the many benefits that immediately spring to mind is the fact that each controller can have pretty much the 'same' named actions irrespective of the task at hand (create, edit, delete, list etc).
couple this with a good repository pattern for the data access and some nifty T4 templates and you more or less get an easily understood 'plumbing' job created for free.
this is what makes mvc a pure joy for me - the discreet segmentation of related operations into a unified structure. as previously mentioned, what could become unweildy and cumbersome is instead rendered (no pun intended!!) familiar and focussed.
I guess if you like spaghetti, you would only have one controller.
Complexity, complexity, complexity, that is the question. Software is all about breaking a problem down into manageable units.
Hence multiple controllers.

ASP.Net MVC View Structure

I just finished Scott Gu's Nerd Diner tutorial. I found it very helpful because it not only taught the basics of ASP.Net MVC, but also how to use with Repositories, Validation, Unit testing, Ajax, etc.. Very thourough, but still manageable.
However, I am curious about his site structure:
Specifically, he used this view strucuture for every object:
/ModelObject/Edit/
/ModelObject/Create/
Then extracted the common elements between the two views and put them into a partial.
I understand the logic, but it seems like it would lead to "view explosion" if you have even a moderate number of tables in your database.
Scott's really good, so I am assuming his structure is right. But I would like to know why.
Thanks!
[Edit for clarification]
I realize that many times it is necessary for there to be multiple actions (and views) to handle differences in creates and edits. It is the case of the very simple edit and create, where the only difference between the two actions is in one case the model has an ID and needs to be updated, and in the other case the model does not, so it needs to be inserted.
In this case, is the violation of the "Dumb View" rule by using the same view to handle both cases going to cause major problems?
The view structure is based on the controllers, not the model directly. In the Mvc methodology, you should have a view for each action (each public method, essentially) in a controller. The controller actions don't have to match up directly to each table in database but there is likely some sort of direct relationship between the number of tables in the database and the number of controllers and views. Controllers are higher level
It is standard to have CRUD type actions on the controller, when they are applicable:
Index: list the items
Details: view a specific item
Edit: edit an item
Create: new item
Delete: delete an item
Each of these actions will require a view (and sometimes more than one).
So, yes, you can collect a large number of views if it is a large application. The way to minimize the code is:
Extract shared functionality to partial views, as to keep the action views as small and simple as possible
Keep the views and controllers simple so that they are easy to maintain
Use AJAX to implement more functionality in one view
It's important to point out that any large application is going to have lots of forms. Whether it's Mvc or Web Forms, if there is a lot of data to work with, there are going to be a lot of forms necessary to do it.
It is true that this can indeed lend itself to a lot of views. However, I've found that in my real life applications, I'll have a number of tables that I don't have a 1:1 correlation to CRUD operations. While I certainly have data that goes into those tables, I've found that most times a view presents data from at least two if not three or more tables. Just like every other application, you've got to know what you're after so that you can plan things out. Any large size application is going to require quite a bit of planning up front (which would include analyzing the number of views/controllers for MVC).
It's only the small apps that you can sling together based on you hunches and past experience.
if you have a background as asp.net webforms developer, your answer is natural.
There are several questions, it depends on the point of view. At first, with asp.net-mvc we do not have fully-equiped server controls making many things for us, without a real awareness what they do. Now you have to type more code and have eyes like a surgeon on html.This way I can find a reasonable question for "view explosion"
Other projects follow more or less that structure, see the project by Rob Conery:
Mvc Storefront
PS: "Skinny controllers, Fat Model and… Dumb view"
[Update response to clarification]
Mhh.. I think there's no violation of "dumb view". The important thing is that the all the views has nothing to do with the code in the business logic layer or in your model. You can a have a button "Save", it is the controller has to know which action must be executed, insert or update.
On more reflection, this is what I am thinking:
Combining the edit/create views would be easy on simple models because
- Same properties displayed
- Same validations
BUT doing this would force you to either
- handle both the update and insert in the same action
- use a control statement in the view to determine which view action is used to update
Both options seem ugly and unnecessary when it is so easy to use separate actions and separate views with common code extracted into a partial.

Resources