ASP.NET MVC Controller design - asp.net-mvc

I have a question about how to design my controllers properly.
Project is fairly simple: blog, immage gallery with categories and images inside them, news secion.
However I don't know how to organize my controllers for this because I want to make somewhat admin panel where administrators can edit, add and modify these things. I've came up with 3 scenariosu so far...
Admin panel will have links to site/controller/edit, but layout for these action results will be different from standard one.
Admin controller will have all these actions like BlogAdd, BlogEdit so that url will be something like /site/admin/blogedit.
Create copies of Blog controller in admin folder so url will be like /site/admin/blog/edit - i sense problems with routing since 2 controllers with same name does not sound like a good idea, however I like ho URL looks in this situation.
What I'm trying to make is CMS somewhat similar to wordpress, where blog creation,editing and deletion is completely separated from default blog itself.

I suggest you stop thinking about URLs and Controllers being a 1->1 relationship. This will make things MUCH easier and less confusing. You can make the URLs work however you want with MVC's routing mechanism and there's no reason to restrict your controller design/organization because of the URLs you want, because you can always adapt the routing to with with the URLs you have in mind.
While building the website, just focus on the controllers (and the general interface) and ignore the URLs until you get to that point, and then when you come up with a good URL scheme go into the routing system and add the routes to connect to your existing controller actions as you want.
Once you code out your blogging engine you will have a much better idea of the user workflow and will probably find different ways to organize your URLs, and you can then reorganize your URLs without touching the controllers themselves.
As to your first requirement:
There are two ways to do this depending on your end goal. If your goal is to display the same core content, but have different user options available (different overall layout, additional buttons on the page, etc..) then the best idea is really to just pass in an IsAdministrator property in your view model, and make the slight changes to the page based on if that's true or false. The reason is because you still (most likely) want the core of the page to be the same, and this keeps you from duplicating code that is related to the core data (data that's being displayed for both admins and non-admins).
Edit: So in summary, organize your controllers based on what makes it easier to develop with, not based on how the user interacts with the system with. You can always change the latter, changing the former is harder and will make maintenance annoying.

You can create Areas in your MVC project and have your admin functionality in a controller in your admin area.
This will allow you to easily seperate your administration functionality from your general blog functionality.
That's how I'd do it.

Why don't you keep the routes the same and handle the different roles via security? For example:
/blog/name-of-topic/view to view a topic (all users)
/blog/name-of-topic/edit to edit a topic (only enabled for logged in users)
/blog/add to create new topics (only enabled for logged in users)
You can handle these actions in a single controller and decorate the actions that require logged users via the [Authorize] attribute. Same thing with the links on your views, you would enable the links to edit and add topics only to visible users.
You could still have a separate panel to allow admins to hit the aforementioned add/edit links .

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.

Orchard CMS and controller vs driver

I am a little ashamed for asking so many questions, but I really want to learn.
In Sipke's blog a webshop is created. There is one specific question that boggles my mind when trying to do something similar.
Let me spell out the basic requirements:
User registration form and login, etc. This one is covered by the blog and it works nice.
Creating product parts and so on. This one is covered and no problem there.
Ordering by filling in an order form and making the payment. See down
Having the order page maintainable by customer. See down.
Viewing your own orders and their status. See down
Maintaining customers and orders from backend system. This one is covered by the blog and I need to do some work there yet.
As for items regarding creating orders and viewing your orders. I have followed the approach for creating records and using standard MVC controllers. But then I encountered problems:
Menu for orders page. This I had to do manually after installing the module.
The order page itself. I had to create the view including title and so on. But I can imagine a customer wanting the order page on another menu and with a different title. And maybe add even some own content to the ordering page. This I couldn't achieve by using standard MVC approach. So maybe I am using the wrong approach here. So I was thinking about using contentparts for creating an order and displaying them and using the drivers and handlers for that. But before I go down that road and refactor everything I want to know if that is the right approach. A downside could be that once the module follows that route it can then not so easily be reused with customers that have other cms's capable of hosting an MVC3 module.
So when to use drivers, handlers and contentparts and when to use standard controllers and views.
You should use Drivers and Parts (with Handlers if needed) when you want to create functionality for content items. E.g. if you want to display a custom media with all products, you could create a Part (together with its Driver, etc.) to handle that. Read the docs on Parts.
If the functionality is not tied to content items the most possibly you want to use the standard MVC toolbox, it's fine. Look at the built-in modules how they do that. E.g. the Blog module uses controllers and views to show the admin UI, but has parts to enhance the functionality of for example the Blog content type.
To make things more complicated you can employ ad-hoc content items to build a page that you'd normally do with simple views, but that's an advanced topic :-).

How to place logic for several different roles in ASP.net MVC 2

I am a bit new to ASP.NET MVC and I have a bit of an ordeal. I am developing a website with several roles in it and of course the logic and gui that the user gets depends on the role (duh).
There are 10 separate roles in this application. They do share most of the same functionality but some screens will be different depending on which roles they are in.
Heres my question. All examples and tutorials I've read on the internet and the Apress book that I have been reading show an example how to implement roles with one role (Admin) in which the common way is to provide an Admin Controller (or even Admin area) for the authorized section of the site. However, what if there are 10 roles? Do I really need to code up 10 separate controllers?
Let me help the question by giving detail what is being developed. There will be a menu and the menu items will be filtered by role of what views(or pages) they can and cannot get.
The from what they select, it will provide them a restricted view(or authorized page) which from within will provide a plethora of functionality limited to just that role.
I know there are several different ways to do this, I just want to know what is the recommended or "clean" way.
Have any of you been in this situation and if so, how did you organize the logic for multiple roles? Separate all roles to separate controllers? Have few controllers but just apply authorize filtering on the action methods? Apply the role filtering within the views or partial views and leave the controllers alone?
Unfortunately there are little resources for how to implement several roles out there, I just want to know how to do it the "correct" way in terms of separating the logic.
I would put the pieces of functionality into partial views. Have one controller per piece of website and load partial views based on the role and what should be exposed.
I would only stray from that if you have an excessive amount of differences, like an administrator would possible have. Then I typically make an area to encapsulate that functionality.
Regardless of the controller separation I would definitely use partial views to minimize duplication of similar code. You will reap the benefits when you need to maintain that code.
Use Authorize on the action methods and apply the roles allowed for the operation.
Depending on what's appropriate for the scenario, build a list of available actions from the controller and send that to the view as part of the view model. In some cases its more appropriate to send a simpler view model that tells the view whether each operation is allowed i.e. CanDelete, CanEdit, CanViewDetailedInfo etc.
I'd start with that, and depending on the actual complexity re-factor to any combination of:
An ActionFilter that populates the available actions / instead of explicitly doing it in the controller
Use reflector to look for the list of roles applied in authorize / so you only specify roles once
Your own html helpers that take authorization into account. So when you declare an action link, its only output when the action is supported.

ASP.NET MVC: Use existing Account or create new User controller?

I'm creating a new ASP.NET MVC application. So far I've used the Account controller for actions related to a user's account -- Login/Logout, Activation (like Register, but I use Register for other actions in the site so I've renamed it), Add/Update Contact information. Up to now, though, I've been concentrating on the administrative user views.
I'm at the point where I'm going to start creating the various views that non-administrative users will see. These are rather limited compared to the administrative interface. My inclination is to create a new set of views and associated controller in the User "family" instead of using the Account views/controller. Is this a good idea or should I stick with the Account controller? My feeling is that since this is for ordinary users it should be a separate controller since Account would apply to both ordinary and administrative users.
EDIT: After reading the first couple of responses, my refactored question is:
Do you consider the Account controller to be for administrative actions related to the user's account or for all actions on the user's account? Would you distinguish between membership/role related views/data and application related views/data to the extent of creating a new controller.
Related, but doesn't directly answer my question: ASP.NET MVC Account Controller usage guidelines?
I don't think there's a right or wrong answer here, so I'll give you my opinion.
Technically, either solution (extending the Account controller or creating a new controller) will work just fine.
So I think this is more a question of how the users perceive the functionality. I think it's a good idea to follow the convention that the URI dictates the controller (or vice versa, if you prefer).
If, for example, you'd like to have the "administrative" actions on a separate path, then that should be a separate controller. You might want to do this, for example, if you use an IIS module for authentication or if it makes your log analysis easier.
On the other hand, it might be the case that the users perceive account functions and administrative functions as part of the same family of actions, except that some users have additional features. If so, then that suggests that should be on the same path in the URI and, hence, part of the same controller.
Summing up, I think this is a question you should ask your user representative instead of folks on this site. :)
Update: Regarding your updated question, I would say that it is fairly natural to put an action for changing a user's password on the Account controller, and that action could be invoked by the user herself, not just an administrator. So I wouldn't presume that the Account controller is strictly for administrative tasks. On the other hand, your example of the fund-raising performance is well outside of the scope of membership-related things, so it is not clear that it belongs on Account, either. I'm still leaning towards, "ask your user representative."
In ASP.NET MVC you will usually create controls based on data types rather than access types. For example:
Instead of 2 /Controllers/UsersControl.cs and /Controllers/Admin/UsersControls.cs it is easier to use one common controller for both admins and regular users - /Controllers/UsersController.cs (by setting different [Authorize] attributes and views).
I would keep existing AccountController.cs for encapsulating account related functionality. And just add new UsersController.cs for the rest Users related functionality (which could have methods like OnlineUsers etc.)

ASP.NET MVC controller actions design

I really like the way ASP.NET MVC works. I'd love to implement it on all new web projects moving forward, but I hit a snag in a prototype the other day that I really haven't found a good solution for, so I ask you, how would you design an MVC app that doesn't fit the typical REST pattern? As an example, the prototype I was designing would have several pages, but the pages themselves aren't necessarily bound to a domain model. For example, take a simple registration site, which might have the following pages:
/Default.aspx
/Register.aspx
/ThankYou.aspx
Occasionally, such a program might require an admin section to deal with such details as moderating sign ups or reviewing data. In a standard ASP.NET web app, I might add the following
/Admin/Default.aspx
/Admin/ListRegistrations.aspx
/Admin/ViewReports.aspx ...
Would it be an unacceptable deviation from the MVC pattern, in this case, to have two controllers such as:
Home->Index
Home->Register
Home->ThankYou
Admin->Index
Admin->ListRegistrations
Admin->Reports
My frustration with this is compounded by the fact that there is no real solid implementation of subcontrollers and areas yet. I'm aware of the "Areas" prototype put together by Phil Haack, but it's not very mature, and quite frankly, I'm not sure I like the way it's setup, but I don't really know how I'd like to see that work either.
I guess when I think MVC, I tend to think REST as well, and having controller actions that represent pages rather than actual entities or actions doesn't sit right with me. What do you think?
You can always mix ASP.NET Web Forms with MVC.
Just add
routes.IgnoreRoute("Pages/{*path}");
to your routing table and add traditional Web form pages to Pages folder of the application.
One mistake that newcomers to MVC make is to group actions into a controller for display reasons. In your case, instead of grouping the Register and ThankYou actions in with the homepage try separating them out into an AccountController as the MVC team has done in the sample project. You can use routing to set the Url's up however you want for the end-user.
As for your other actions, how about a ReportController? You could then additionally have an AdministrationController whose Index action/view contains links to various admin actions, including those on the ReportController.
Short Version: Group actions into a controller by function, not site navigation.
I usually ditch the "Home" controller as the first thing in a project and replace it with a "Page" controller. I use that one for anything that is "just" a page. Things like "FAQ", "Contact Us", etc. I do this at least partially because the default approach to the Home controller requires a new method being added every time you need even a basic, static page.
In that controller, I only have the one action: Display. That action gives all of those pages the same context object. I actually store the content for those pages in the database with a lookup "slug" and tie it into NVelocity templating, but even just static HTML or NVelocity templates in files would work too.
Anything else, like the others said, gets split into controllers by the "thing" being managed. So, a ReportController, User or AccountController, CartController, etc. Then the actions make much more sense.
When you're talking about listing the registered users, it's actually a list of users, so I'd have a UserController and do /User/Display/Registered/MostRecent or something similar. For the registration itself, /User/Register which would post to /User/SaveRegistration which could, in turn, redirect to /User/DisplayProfile/NewUserID or /Page/Display/Home from there.
You can have as many controllers as makes sense; that layout looks reasonable. Note that routes don't have to map directly to {controller}/{action}, but it keeps things simple. Looks fine to me - except I'd probably have ThankYou as a view - i.e. the Register [GET] perhaps uses a different view to Register [POST]

Resources