ASP.Net MVC & Memberships - asp.net-mvc

I would really appreciate some feedback on what I am trying to achieve:
The problem:
I would like to authorize a user of my application to a single action on the controller. For e.g.: a user can perform the "save" action on my controller class if he has the required authorization.
In the project I am working on, the creation of roles & their authorization is done by the client deployment team & not in my control. So, I program to a "control point" which can be assigned to role/user, while my application needs to only check that control point.
How do I get a control point concept into ASP.Net MVC? More specifically, how do I enable/disable buttons on the View based on the user permission on the controller?
My solution:
Ref.: http://weblogs.asp.net/fredriknormen/archive/2008/03/12/asp-net-mvc-framework-2-interception-and-creating-a-role-action-filter.aspx - as a starting point
Instead of creating a role filter as explained in the link above, I would have a ControlPointFilter class which would get the model & do the authorization check.
The trouble I have is in the View class & I am currently passing the control point collection to which the user has access in the ViewData[] collection.
In the View class, I am checking if the related control point is present in the ViewData collection (which I don't like - want to keep the code to a minimum in the View class)
The other issue is - while the actual control point name is being set in the attribute to the controller class, where/how can I pass these attributes to the view & yet keep the view clean?
Hope that helps & appreciate your time/effort to answer this!
Sunny

One possible solution to this is to translate control points into view attributes in your controller actions (perhaps these are the same things, though, it's not clear from your question). The idea would be that your control point would translate into meaningful view directions such as "AllowEdit", "AllowSave", "AllowDetailedView", etc. These would become entries in ViewData.
Use a base controller class to extend Controller and give it a ControlPoint collection. Have your filter populate this collection in the controller. Have the base controller OnActionExecuted method use this collection and, in the case of a ViewResult, populate the ViewData with the appropriate values for the collection of view directives. Individual controller actions could also use the ControlPoint collection to determine whether they need to provide data for individual views based on whether the view will render extra data or not.
In your view, rely not on the control points themselves but the view directions determined by the base controller. This way you've decoupled the views from the control point logic. Views only operate on view data in ways that are meaningful to the view, not on permission-based data that have meaning in the context of the application. The view won't care how or why the particular directive gets set, it only needs to render appropriately based on the value of the directive.

Hmm, could you not simply create a templating system, to assign roles to users? I.e. create a user template "Power User" that has the roles "CustomerService" and "ConfigurationEditor", and then use the role system as pr usual (i.e. Roles.IsUserInRole(username, rolename))?
For actions, you then use
[Authorized(Roles="CustomerService,CustomerServiceAdmin")]
public ActionResult Edit(...)
{
}
For views, you use
<% if (Roles.IsUserInRole(Context.User.Name, "CustomerService")) %>

Related

Connection between model, view and controller

I've searched a lot and read a lot about the concept of MVC. But I still don't know how to connect them together. Suppose I have a controller class, view class and model class. If user did something in that view, view should notify controller the action and controller may need to communicate with model to get some data.
Now, does view hold a reference to the controller? Does the controller has a property of that model? Or they just using like "include"?
The data is saved in memory, or database? Memory means stored in variables.
More complicated case, one action from user may need many controllers and models involved. How to co-ordinate them together?
What I've done before is I create a "view controller", which has view and some actions of that view.
And sometimes there is no model. All data is passed by parameter. If there are some models, some of them are singleton so I can get it everywhere.
This is a very generic answer, depending on your system these can vary:
The Controller has a reference to the View, an IBOutlet for example. The View is not aware of the Controller, it's a dumb thing that receives info and displays it, that's it.
Depends on what you have in place, sometimes you don't need to persist the data and being on variables is enough. For persisting data, you have CoreData, plists or save them on the sandbox.
Normally you could have a parent Controller, holding references to child Controllers. Each child should be independent and the parent would be the "glue" between them.
I can point you to this repo I created, called iOS Architecture, to help you understand how the controller and the model interact.
Here are some more points:
When your Action returns a View("SomeView"), it will check first if you have a layout, if not it will look for SomeView.cshtml in the Views folder of that controller.
If you want SomeView to talk to any Action in the controller, what you can do is to do a FormMethod.Post and assign the correct model and of course the Action name. That action name should be decorated with [HttpPost] or you can do a FormMethod.Get and decorate it with [HttpGet] or just leave it blank since [HttpGet] is default.
If you want another action redirecting first to another action without going to a page, you use RedirectToAction() instead of View and change the type to ActionResult instead of ViewResult
I hope it makes sense to you :)

Creating a model for MVC

I'm building my first MVC project and I have a question about the model.
Each webpage can only contain 1 model, yet my page will require 2 models, one is the search option (the ability to narrow your search such as selecting price range, colour etc) as well as the data.
Is it really as simple as creating a new Model, similar to a ViewModel which in this case would only have 2 properties, a SearchModel and a ProductModel?
Yes, there are really two "models" which is sometimes confusing. There's the "View Model" and the "Domain Model." The view model is passed directly to and from the view. The domain model describes the real-life domain that you're dealing with and is what the database persists. Often, they are the same thing, such as if you're displaying information for a single real domain object (e.g., a car). If you have two domain models that go on one page, you should make a view model with both as properties.
If you are looking to have two models in a view then this question might provide useful information:
multiple-models-in-a-view
Edit:
A good example is the 'Manage' view in the default 'Account' controller of a fresh mvc app. It uses a partial view to handle the changing of a user's password. Whilst both views are using the same model type it shows how to implement a partial view. In this case both the main view and the partial are submitting to the same method on the controller, hence they need to use the same model (which is a parameter for the controller method). But if the partial were to invoke a different controller method then the submitted model could be different. Hope this makes sense :)

Returning ad-hoc view models from ASP.NET MVC2 Controllers

I'm porting an existing system to ASP.NET MVC2. In the current legacy app, the user can select from dozens of available fields to customize CRUD forms for different entities in the domain model, similar to the way ERP systems allow customization of core modules.
My question: I'm looking for a good pattern or example for this kind of behavior in ASP.NET MVC2. It seems to me it's rather like creating a ViewModel dynamically based upon user choices, or perhaps the right approach is data-driven view pages that aren't strongly-typed where I can reflect over the results client-side to determine field headings or something -- if that makes sense :). Or maybe I can drive AutoMapper or similar dynamically # runtime based on user choices?
The underlying domain model is EF4-based and I'm using a simple Repository pattern # present for the ViewModel.
TIA for any input! Michael
If I didn't find anything else that matched the needs and went on to do it custom, I would:
Use the ViewModel with all the fields / not just the ones the user picked.
Pass both the ViewModel and the view configuration to the view
Call some html helper that for each item in the configuration adds a field with the corresponding property in the model
The configuration could be passed as either part of a containing ViewModel or in a separate entry in ViewData
Depending on what you need, building/passing the view configuration could be put in an Action Filter. Alternatively the helper could pull it directly.
A different approach is if you need completely custom fields. I mean user defined fields. If that's the scenario, that's not typed at the controller level already, so I'd pass the list of fields/values to the view. The view can do a foreach on those adding the fields. Again that could be moved to a HtmlHelper.

Code behind user control

How would one go about performing controller actions from withing an ASP.net MVC user control?
My scenario is that I have a userID and I want to transform it into a name from the database. To do this I've annotated my model with a display type and put a User template in the shared display templates but I'm not sure where I should write the code which does the lookup to convert from userID to user name.
I think that code ought to go into your models and you should be calling it in your controller and passing it to your user-control in a viewdata. This is if I understood your question.
I would just have the model expose the name and not the userID. This way your view (user control) is only displaying the name and not trying to do a DB lookup. Your "User Control" model would be responsible for how it gets the name, i.e. the DB from your question.
In short, you don't do that.
You should be passing the necessary data to the MVC user control from the View, which in turn should be getting it's information from the controller.
The view (or user control) should not have any knowledge of the controller. You may want to use RenderAction instead of a user control if you feel that the view shouldn't be responsible for passing the necessary information into the user control.

Accessing Controller Properties from a View

I have a User object on a Base controller, this is the standard type of User object you have with the .Net Membership Provider. I need this is decide if users have access to actions, views, and so on.
I am having a problem whereby I want to display user information on the Masterpage. Like a login view from WebForms. I tried to access the User object from the Masterpage but I can't.
So:
Am I breaking the separation of concerns by checking if the user is logged in on the view (simple if statement which changes what is displayed).
Can I simply access the base controller namespace to access this property or is there something wrong with that? When do the controllers get initialised?
As I write this I consider that having my base controller have this property might be a bad idea on the first place.
AGHH!! How would you handle checking user information to change the Masterpage.
Use this:
<% var user = ViewContext.HttpContext.User; %>

Resources