ASP.NET MVC Routes to Mimic Object Graph Traversal? - asp.net-mvc

I'm new to ASP.NET MVC and all tutorials, samples, and the like I seem to find are very basic.
Is it possible (and if yes, a good design) to have routes like so:
.../Organization/10/User/5/Edit
.../Organization/10/User/List
In other words; can the urls mirror your domain model?

Possible, yes, with a route something like:
"~/Organization/{orgId}/{Controller}/{id}/{action}"
Whether it is a good design or not I couldn't say for sure, only that it seems rather complicated to me.
If you have multiple User tables, one for each company, it might make some sense.

Unless there is absolute necessity, keep routes decoupled from object model relations. Otherwise you will have to rewrite routes on every change in model.

"If you have multiple User tables, one for each company, it might make some sense."
Why only then?
"~/Organization/10/User/5/Edit"
... gives me the organization context at all times.
I didn't say so in my first question, but I've written an action filter that authorizes according to the rule that the logged on user must belong to the organization of the current action (hence not being able to see/edit/whatever user(s) of another organization).
I'm not saying that it's the best solution, but if not implementing this cross-cutting concern (aspect) as an action filter knowing the org id (via the action params), how would you solve the authorization issue elegantly?
As I initially stated, I'm new to the world of MVC and very excited about the answers.

Related

Rails: Handling permissions for individual tables and composite views concisely

I'm struggling to find/understand the Rails concept for handling table permissions and permissions for composite views (and composite updates).
Logically, Create, Read, Update and Destroy permissions for tables should be at table (model) level. If I know exactly which permissions a user has on a table, then it is possible to derive from that whether the user has the necessary permissions for any particular view (which just consists of data from one or more tables), and I should never have to repeat these permissions.
The 'Rails Way' would therefore seem to demand a controller for every table (model) that will be used by the application, in order to set permissions for that table in a precise way (using before_action or whatever to validate the user for the particular CRUD action). (Aside: I'm not even sure if there's a good reason for not moving the permissions logic into the model itself, which is actually what I did initially before trying to adhere to convention a little more.)
However, Rails (and possibly MVC in general?) seems to dictate that there should only be one action/view per request. So if I want to make a view consisting of three 'index' views, one for each of the models A, B and C, I need another action/view and a new validation rule for this action. This new validation rule, of course, shouldn't be necessary; the user is allowed to see this new composite view if they're allowed to see each of the individual 'index' views (or more precisely, the data underlying these views).
Also, any Create/Update/Destroy params received relating to a specific model should ideally be passed to that model's controllers for validation/execution (and there may be parameters for instances of multiple different models). I don't think this is typically how it is done, however, because it would require multiple actions being called.
Have I misunderstood the Rails methodology for handling this, or is it really expected that you effectively repeat yourself with regards to Create, Read, Update and Destroy permissions for composite views (and composite updates)?
First off the Rails framework does not ship with any provisions for authentication (well except has_secure_password) or authorization (permissions) and is totally unopinionated on the matter.
There is no "Rails way" to handle authentication or authorization.
What Rails is geared towards is the Rails flavor of REST which is focused on exposing resources through a structured API. Each controller handles a specific resource or just a specific representation of a resource.
Note that a resource is not equal to a table. Tables are an implementation detail while resources are the abstractions that your application provides as a public API.
Of course since the framework is not opinionated towards any form of authorization you can roll your own in any fashion you want such as RBAC, ABAC etc.
Of course there are several community gems such Pundit and CanCanCan that remove the need to reinvent the wheel.
(Aside: I'm not even sure if there's a good reason for not moving the
permissions logic into the model itself, which is actually what I did
initially before trying to adhere to convention a little more.)
There is a very simple reason why this is a bad idea. Models are not request aware and do not have the proper context for authorization.
A much better alternative is to use a component like Pundit that compliments the traditional MVC structure, but is its own separate entity - you could even call it MVCP.

Rails - Method in Model or Controller or somewhere else?

I'm practicing my Rails development skills by building an app that will have different types of exercises for users. Most probably things like multiple choice questions for different subject matters.
One way to check to see if the questions are answered correctly is to use validations on the model. However, I don't really need to save the results, and it might end up in me creating a lot of different models, as each question will have its own validation to check each answer.
Is an alternative to create a new Controller action for each subject area? Is
How else might I organize this?
http://www.enode.com/x/markup/tutorial/mvc.html
With the MVC pattern, Controllers are usually in control of manipulating data kept by Models.
It's good form to keep most of your logic in your Controller. I'm not sure what you mean about a new Controller action, but what you'll probably want to do is set up some sort of form in your View, (see form_for) and fire that off to the Controller. The Controller does validations or whatever you need it to do.
This should be helpful:
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html
So for example, you might have a form in your View (a quiz for example), calculate a user's score in the Controller, and save that as a field for a user in your database.
The debate on where to put logic is as old as the involved patterns themselves. For MVC, I decided to ask myself:
Is the logic involved essential for the model?
Would the model (in itself) function well without the logic?
Is the model free of any requirements towards the controller?
If I'd re-use the model, would I want to take the involved business logic along or would it be in the way?
My general advice: Put business logic as "low" (bottom: db, then model, then controller, then view) as possible without violating any of the following constraints:
Authentication and authorization does not belong to view. It's either a property of the controller (handle things like sessions and general api access rules, etc) or of the model (authorization: who may access which content?)
UI/display/input-method related things do not get into model or db. Don't let your model/db decide if and how to render html, xml or json.
Data consistency and integrity not in controller/view. Ideally, your data model only accepts valid data, uses transaction safety and reports back failure or success to the controller. Ideally, consistency is handled at db level.
A model shall be reusable with other controller/views in new project (think of switching to another web api). Too heavy constraints may render it unusable in new situations.
there might be more...
And generally: If in doubt, put in into the controller. ;)

RESTful vs custom page flow, what's the right approach?

Newbie question, go easy on me :)
I've been struggling with reconciling the concept of designing entities of my system according to the RESTful model and with actually organizing the flow of my site in such a way that it's logic and makes sense to both me and the customer. Let me give you an example:
Let's hypothetically say I'm implementing a site for sharing movies in real life. You got a model for movies, and you got a model for users (with some auth / authz thrown in). I imagine it would be pretty straightforward to treat the movies as a REST resource and let users browse through them, and then you could have a series of relationships (joint table(s)) that would represent ownership, borrowing, and lending. So far so good.
Now, any site out there will have a concept of a user dashboard where you can see the current full state of the user and information related to him. Is the dashboard somehow a REST resource as well? I'd imagine it can't be because it really is very specific to each individual user. Where do I place it then? Do I just create a controller called UserDashboard and perhaps route the root (mysite.com/userdashboard) to a default action from the UserDashboard controller which can, for example, given the user id, display all of that user's relationships in the system?
Is that Rails way? Am I somehow breaking the RESTful paradigm that way?
Thank you!
You can go two ways with this:
You can create an entity that represents the dashboard of your user and store seperate data in that entity, or you can create an action on the controller that represents the dashboard. Both would meet the REST standard as you'd uniquely identify a Dashboard by going to either /Dashboards(db_id) or by going to /users/4/Dashboard, either URI identifying a unique entity.

How far to 'drill down' roles in a .NET MVC application?

I've written a few complex MVC applications which are all role based and use .NET Membership. On my first project I used roles with structure similar to this:
Admin
Manager
Approver
I quickly discovered that wasn't very scalable, for example a customer would say "I want specific user x to have all manager privileges but not delete". I would then have to put a hack in the controller for that user.
Therefore, my second implementation led to this role structure:
CanCreate
CanDelete
CanEditAll
CanEditOwn
This approach then led to literally dozens of roles based on whether they could edit particular items globally or just their own etc. It also leads to a lot more controller actions and considerably more code - though maybe thats just the case in a complex application!
My question is, am I approaching this in the correct way, and are there any good online resources on the "correct" way to approach complex applications with loads of roles. Am I doing this correctly?
Indeed it's very interesting topic and I found myself struggling with the same problems as you do.
I read Derick Baileys interesting blog about that "Don’t Do Role-Based Authorization Checks; Do Activity-Based Checks" : http://lostechies.com/derickbailey/2011/05/24/dont-do-role-based-authorization-checks-do-activity-based-checks/
but had not time to experminet it myself.
A year on from this question I handle things a different way across projects. I'm now sticking to the classic roles of:
View
Edit
Delete
Add
BUT the action methods themselves return data like this:
var order = or.MyVisibleOrders().FirstOrDefault(x => x.Id == Id);
The logic for what is viewable and what is not is then handled by roles in the repository. The database will essentially never be queried for the restricted items in the first place.
Basic stuff but felt I should follow up on myself.

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.)

Resources