Accessing Controller Properties from a View - asp.net-mvc

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; %>

Related

How to get authenticated User in WebApi outside of controller

When in a controller I can just access the User property. Outside of the controller I obviously cannot access the User property so after some reading I try HttpContext.Current.User, but HttpContext.Current is null. This seems quite simple and I would rather not change my architecture so that I pass the user from the controller onto my other classes.

MVC passing values through several views

I have a login view for a user to authenticate: after he inserts his username and password, the next view has a section with welcome, username message. I pass this information through a ViewBag.welcomeMsg and everything is smooth.
When I advance to another view, that section no longer contains the message as the ViewBag.welcomeMsg is defined in the first login controller and gets erased after that.
I don't want write in every controller ViewBag.welcomeMsg = "...";
My question: is there a way to pass a variable like ViewBag that persists and can be accessed from every view of the web application? Like a static field?
If you just want to show the welcome message on your view when user is authenticated then just modify your view like this :
#if (Request.IsAuthenticated)
{
<text>Welcome, #User.Identity.Name</text>
}
Can check with the TempData which will be available till start of the next view rendering. so that you can set it to the other viewbag from tempData.
It very much depends on how you handle the authentication process. If you are using FormsAuthentication for example, then the user information will be stored in User.Identity.Name. You can access User property from various contexts like controller, view, etc.
On the other hand if you are handling the authentication by yourself, my suggestion to you would be to do any of the following (I am writing this from top of my mind, so if I miss a name of a property, forgive me):
Store username in a cookie, and in Global.asax handle PostAuthenticated event where you will read the username (if authenticated) from the cookie. After that create a GenericPrincipal object with GenericIdentiy and assign it to a Controller.User
Store the information in a session (the easiest of all) and pass it around. However, the problem with this is if you have a sessionless controller in which case you cannot rely on this approach.
I wrote an article a long time ago about working with roles and principals, but you can get a picture on how to handle your problem with this solution http://mvcdeveloper.wordpress.com/2013/06/08/passing-user-roles-to-httpcontext-user/

.NET custom authorize attribute (mvc)

In certain Controller I have CRUD methods. In order to access these methods user needs to be logged in. This is why I used [Authorize] attribute for this controller. Now I need additional attribute which would check if item that user wants to view/delete/update belongs to him.
Is it possible and recommended to do this with attribute or you would suggest using check methods inside each method? If you suggest using attribute, could you please provide me some links/instructions?
EDIT:
Ofcourse, if attribute returns false than I don't want to redirect user to login page but show him an error message...
It can be done with a custom Authorize attribute, but it's much cleaner to put the logic inside your controller methods.
The attribute is related to the action being called (the controller class method). On that basis any attribute relating to the user's ownership of the object being manipulated (from your Model) should really be on the entity/class that the user is attempting to manipulate. You'll probably find it easier to validate the user within the Model method rather than using an attribute to achieve this.
In my opinion it is possible, just google for 'Custom Authorize Attribute'.
But maybe it is better to query your database with something like this:
ContextOrSession.Query<Something>.Where(Something.Groups.Intersect(User.Groups).Count>0)

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.

ASP.Net MVC & Memberships

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")) %>

Resources