When should you create separate controllers with ASP.NET MVC? - 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.

Related

To Use or not to user Areas in ASP.NET MVC

I have a project in ASP.MVC5 and Im in the middle to decide if I use Areas or not.
The project will have 3 types of applications inside:
Customer users
Interal users
Support users
The hole application will share the login page, and depending on the user type Im planning to redirect to the right Area.
So I was thinking on the above idea or just use the default structure and then have:
Views/Customer/and here my views
Views/Internal/and here my views
Views/Support/and here my views
Any advice?
If you are going to have similar controllers and models and views for each different "module" (Customer, Internal, Support) then areas would help organize it. For example, if your customer is going to have OrdersController (Edit, Display, Create etc.) and the corresponding models and views and your Support will also have similar controllers, models and views then it is worth creating areas. That way your routes will look like this:
~/customer/orders/1/edit
~/customer/orders/create
~/support/orders/1/edit
~/support/orders/create
But if that is not the case, then it is not worth it because areas do tend to make things a little more complicated.
I would start with the simple, no areas, structure firstly. If you see the need for areas then create them.

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.

Organizing ASP.NET MVC Solutions

I have been working on a large ASP.NET MVC 3 application for a few months now. It wasn't until late in the project that I realized that my controllers were HUGE! Part of the problem with these controllers being huge was that I couldn't unit test them.
I've since split the responsibilities of the controllers into four tasks (in my mind):
navigation
converting IDs to data objects
building view models for display
general-purpose business logic
Since some business logic is shared across client- and server-side code, it doesn't make sense to mix it in with view model builder logic. So, I immediately see the need for at least two projects: view model builders and general-purpose business logic.
I realized that navigation should be the responsibility of the controller, so that logic stays in the MVC project.
I am a little torn about which project should be responsible for converting IDs to data objects. Originally, I had made this the responsibility of the business class/view model builder class. However, I think I would like these classes to work primary with fully-constructed objects. So, I am not sure where in the code this conversion should take place. It doesn't seem to matter where I do the conversion, the code becomes duplicated. I have been thinking about creating adapters in the respective projects that do these conversions and then call the actual business class/view model builder class.
Has anyone worked in an ASP.NET MVC project that has grown beyond a single project?
How is logic broken out to keep the size of controllers down and keep code testable?
Has anyone worked in an ASP.NET MVC project that has grown beyond a single project?
Yes.
How is logic broken out to keep the size of controllers down and keep code testable?
By putting controllers on a diet.

MVC Controller design

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.

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