Rectangle 27 16

You can use Following code for role based checking

@if(Request.IsAuthenticated)

{
    if(User.IsInRole("Admin"))
    {
     <Ul Class="SubMenuItem">

     <li> this menu item is for Admin role</li>
     </Ul>
    }
     if(User.IsInRole("User"))
    {
     <Ul Class="SubMenuItem">

     <li> this menu item is for User role</li>
     </Ul>
    }
}
@* For unknown user *@
else
{
     <Ul Class="SubMenuItem">
         <li> this menu item is for Unknown user</li>
     </Ul>
}

I ran into an odd issue using User.IsInRole, getting a 'Unable to connect to SQL Server database' error. I fixed it by adding [InitializeSimpleMembership] on the controller. More discussion here: stackoverflow.com/questions/14521003/

- 1. This doesn't really answer the question. It is an OK solution when you have only a small number of roles, but the question clearly states: "I tried some SO links, but all they are talking about 2,3 roles and it was hard coded. In my case roles may vary and we uses db to set up access for roles."

.net - How to Show or hide controls based on roles - ASP.NET MVC 4 Raz...

asp.net .net asp.net-mvc authorization windows-authentication
Rectangle 27 11

Typically you would want to keep your views as clean as possible with little to no logic. I would suggest moving your role checking logic into a controller action and rendering a partial view based on the users role.

You can use ChildActions and the Html.Action extension method to get this wired up.

A child action method renders inline HTML markup for part of a view instead of rendering a whole view. Any method that is marked with ChildActionOnlyAttribute can be called only with the Action or RenderAction HTML extension methods.

In your project, create a new Controller called Dashboard and added a single Action called BuildTable.

public class DashboardController : Controller
{
    [ChildActionOnly]
    public ActionResult BuildTable()
    {
        if (Roles.IsUserInRole("Administrator"))
        {
            return PartialView("_AdminTable");
        }

        return PartialView("_SupportTable");
    }
}

Include the following line in the view where you want the dashboard table to appear.

@Html.Action("BuildTable", "Dashboard")

.net - How to Show or hide controls based on roles - ASP.NET MVC 4 Raz...

asp.net .net asp.net-mvc authorization windows-authentication
Rectangle 27 13

While I agree that generating urls based on permissions is probably not best practices, if you want to continue anyway you can find the actions and their attributes using these:

Retrieve 'Action' methods: This retrieves a collection of method infos because it is possible to have multiple Controller classes with the same name and multiple methods of the same name in particular with the use of areas. If you have to worry about this I'll leave the disambiguation up to you.

public static IEnumerable<MethodInfo> GetActions(string controller, string action)
{
    return Assembly.GetExecutingAssembly().GetTypes()
           .Where(t =>(t.Name == controller && typeof(Controller).IsAssignableFrom(t)))
           .SelectMany(
                type =>
                type.GetMethods(BindingFlags.Public | BindingFlags.Instance)
                    .Where(a => a.Name == action && a.ReturnType == typeof(ActionResult))
             );

}
public static MyAuthorizations GetMyAuthorizations(IEnumerable<MethodInfo> actions)
{
    var myAuthorization = new MyAuthorizations();
    foreach (var methodInfo in actions)
    {
        var authorizationAttributes =  methodInfo
                .GetCustomAttributes(typeof (MyAuthorizationAttribute), false)
                .Cast<MyAuthorizationAttribute>();
        foreach (var myAuthorizationAttribute in authorizationAttributes)
        {
            myAuthorization.Roles.Add(MyAuthorizationAttribute.Role);
            myAuthorization.Permissions.Add(MyAuthorizationAttribute.Permission);
        }
    }
    return myAuthorization;
}
public class MyAuthorizations
{
    public MyAuthorizations()
    {
        Roles = new List<string>();
        Permissions = new List<string>();
    }
    public List<string> Roles { get; set; }
    public List<string> Permissions { get; set; }
}

Finally the AuthorizedAction extension: warning:If you do have more than one match for a given controller/action pair this will give the 'authorized' url if the user is authorized for any of them...

public static string AuthorizedAction(this UrlHelper url, string controller, string action)
{
    var actions = GetActions(controller, action);
    var authorized = GetMyAuthorizations(actions);
    if(user.Roles.Any(userrole => authorized.Roles.Any(role => role == userrole)) ||
       user.Permissions.Any(userPermission => authorized.Permissions.Any(permission => permission == userPermission)))
    {
        return url.Action(controller,action)
    }
    return string.empty;
}

A Note on Generating Urls Based on Permissions: I state this is probably not best practice because of many little things. Each may have their own level of relevance depending on your situation.

  • If you are already checking permissions in other ways to control the rendering of the page (as it appears you are doing based on your comments elsewhere) this explicitly not writing the url out is pointless. Better to not even call the Url.Action method.
  • If you are not already controlling the rendering of the page according to the user's permissions, simply returning empty string for urls will leave a lot of broken or seemingly broken content on your pages. Hey this button doesn't do anything when I press it!
  • The behavior of the AuthorizedAction method seems inconsistent. Returns a url sometimes, and an empty string other times.
AuthorizedAction
boolean
public static bool AuthorizedAction(this HtmlHelper helper, string controller, string action)
{
    var actions = GetActions(controller, action);
    var authorized = GetMyAuthorizations(actions);
    return user.Roles.Any(userrole => authorized.Roles.Any(role => role == userrole)) ||
       user.Permissions.Any(userPermission => authorized.Permissions.Any(permission => permission == userPermission))
}

Then use this in your razor pages.

@if(Html.AuthorizedAction("User","Add")){
   <div id='add-user-section'>
        If you see this, you have permission to add a user.
        <form id='add-user-form' submit='@Url.Action("User","Add")'>
             etc
        </form>
   </div>
}
else {
  <some other content/>

}

Thank you very much. You explained the items I was totally missing about getting an action and its annotation attributes. It would be great if you also explain why generating url based on permission is not best practice and what alternate procedures can I follow

As I have commented in another answer, "My point is if a MyAuthorization annotation Permission value changes for the action, I have to change this all over the ui where I use the url" That's what I don't want to do.

@Burhan What exactly is your goal with the empty urls?

I am trying to hide the urls to action in view pages from those users who don't have access permission to that action. I could use if else in razor view, but I will require to change these conditions if permission to a action changes

@Burhan As to needing to change razor along with the permissions: See the last section of this Answer:Controlling Page Rendering Via Action Authorization attributes:Html.AuthorizedAction takes the controller and Action same as Url.Action does. It returns true if authorized false otherwise. As permissions on the action change, it does not require updates to the razor to keep in line.

c# - How to get custom annotation attributes for a controller action i...

c# asp.net-mvc razor
Rectangle 27 2

I have done something similar. The way I did it (may not be the best)

in the controller use:

bool showSection1 = true;
bool showSection2 = false;

ViewData["showSection1"] = showSection1;
ViewData["showSection2"] = showSection2;
/// may be better to use a viewmodel here rather than ViewData

then in the view:

@if((bool)ViewData["showSection1"])
{
    @{Html.RenderPartial("section1");}
}
@if((bool)ViewData["showSection2"))
{
    @{Html.RenderPartial("Section2");}
}

you will need to do the logic to set the boolean the way you want them but this should be a start.

you could also create a static method that returns the role and then get that value directly from the view. this may be bad form though.

@if(AppHelper.GetRole().equals("role1")){
    //show the partial
}

then create a class called AppHelper and a method called GetRole that returns the role of the user.

.net - How to Show or hide controls based on roles - ASP.NET MVC 4 Raz...

asp.net .net asp.net-mvc authorization windows-authentication
Rectangle 27 2

As @Antony Teisserie mentioned do create an area name "Admin" so that you can access the admin panel via "your_url.tld/Admin"

razor - How do I create views and controllers folders in ASP.NET MVC 3...

asp.net-mvc-3 razor
Rectangle 27 2

You can use Areas in MVC. Right click on your Solution and Add Area and then you can have multiple areas in your MVC application. You might need to work on route a bit if those are not configured as per your requirement by default. Secondly you can have a plugin Architecture as well where you can have multiple projects clubbed together and all will reffer same Global.asax file.

razor - How do I create views and controllers folders in ASP.NET MVC 3...

asp.net-mvc-3 razor
Rectangle 27 1

Usually I just check the role in a similar way you did and then either render a partial view with the links or just create them. Something like this using Razor syntax. I use T4MVC for actions.

@if(User.IsInRole("Admin"))
{
    <li><a href="@Url.Action(MVC.Admin.User.Index())">Users</a></li>
}

c# - Building an ASP.NET MVC Master Page Menu Dynamically, Based on th...

c# .net asp.net asp.net-mvc security
Rectangle 27 129

I have in the past created a helper function to only return output when a criteria is met like this:

public static MvcHtmlString If(this MvcHtmlString value, bool evaluation)
{
     return evaluation ? value : MvcHtmlString.Empty;
}
@Html.ActionLink("Create New", "Create").If(User.IsInRole("Administrators"))

can u tell me where to write this If method ??????

In a static helper class.

@Neel Create the folder Helpers and add static helper class and put there this code. And later in cshtml at the top put @using Helpers.YourClass

ohh it was almost 3 years ago and now I don't even remember where i was using this @Dimi :P but anyways thanks :)

c# - asp.net MVC3 razor: display actionlink based on user role - Stack...

c# asp.net-mvc-3 razor
Rectangle 27 127

I have in the past created a helper function to only return output when a criteria is met like this:

public static MvcHtmlString If(this MvcHtmlString value, bool evaluation)
{
     return evaluation ? value : MvcHtmlString.Empty;
}
@Html.ActionLink("Create New", "Create").If(User.IsInRole("Administrators"))

can u tell me where to write this If method ??????

In a static helper class.

@Neel Create the folder Helpers and add static helper class and put there this code. And later in cshtml at the top put @using Helpers.YourClass

ohh it was almost 3 years ago and now I don't even remember where i was using this @Dimi :P but anyways thanks :)

c# - asp.net MVC3 razor: display actionlink based on user role - Stack...

c# asp.net-mvc-3 razor
Rectangle 27 41

If you want a code block, that would do in the view :

@if (Roles.IsUserInRole("Administrators"))
{
  <li>@Html.ActionLink("Create New", "Create")</li>
}

Matthieu, I would have normally taken that approach as well. Check out Richard's response.

@Kristofer : In some cases you may want to have a block structure to avoid having html hanging around for example.

c# - asp.net MVC3 razor: display actionlink based on user role - Stack...

c# asp.net-mvc-3 razor
Rectangle 27 40

If you want a code block, that would do in the view :

@if (Roles.IsUserInRole("Administrators"))
{
  <li>@Html.ActionLink("Create New", "Create")</li>
}

Matthieu, I would have normally taken that approach as well. Check out Richard's response.

@Kristofer : In some cases you may want to have a block structure to avoid having html hanging around for example.

c# - asp.net MVC3 razor: display actionlink based on user role - Stack...

c# asp.net-mvc-3 razor
Rectangle 27 3

You can use Following code for role based checking

@if(Request.IsAuthenticated)

{
    if(User.IsInRole("Admin")
    {
     <Ul Class="SubMenuItem">

     <li> this menu item is for Admin role</li>
     </Ul>
    }
     if(User.IsInRole("User")
    {
     <Ul Class="SubMenuItem">

     <li> this menu item is for User role</li>
     </Ul>
    }
}
else
{
 <Ul Class="SubMenuItem">

     <li> this menu item is for Unknown user</li>
     </Ul>
}

Hide and visible the div tags of Layout.cshtml on the basis of user ro...

asp.net-mvc asp.net-mvc-3 razor asp.net-mvc-4
Rectangle 27 7

I've modified Richard's code to provide an optional MvcHtmlString parameter to return if the evaluation is false.

public static MvcHtmlString If(this MvcHtmlString value, bool evaluation, MvcHtmlString falseValue = default(MvcHtmlString))
        {
            return evaluation ? value : falseValue;
        }

c# - asp.net MVC3 razor: display actionlink based on user role - Stack...

c# asp.net-mvc-3 razor
Rectangle 27 7

I've modified Richard's code to provide an optional MvcHtmlString parameter to return if the evaluation is false.

public static MvcHtmlString If(this MvcHtmlString value, bool evaluation, MvcHtmlString falseValue = default(MvcHtmlString))
        {
            return evaluation ? value : falseValue;
        }

c# - asp.net MVC3 razor: display actionlink based on user role - Stack...

c# asp.net-mvc-3 razor
Rectangle 27 2

If you haven't enabled roleManager and you still want to check User's role, you can do it like this:

@if (@User.IsInRole("administrator"))
 {
   @Html.ActionLink("Create New Version", "Create")
 }

What we are doing it here is, we are just accessing user's properties. This can useful if you are managing roles yourself.

c# - asp.net MVC3 razor: display actionlink based on user role - Stack...

c# asp.net-mvc-3 razor
Rectangle 27 2

If you haven't enabled roleManager and you still want to check User's role, you can do it like this:

@if (@User.IsInRole("administrator"))
 {
   @Html.ActionLink("Create New Version", "Create")
 }

What we are doing it here is, we are just accessing user's properties. This can useful if you are managing roles yourself.

c# - asp.net MVC3 razor: display actionlink based on user role - Stack...

c# asp.net-mvc-3 razor
Rectangle 27 3

This answer assumes you are using SimpleMembership's default role manager in MVC4:

If it is just a specific section of the layout you can use Razor. Put this where your menu code is... (which is probably in _Navigation):

@if (Roles.IsUserInRole("GlobalAdmin"))
{
    @Html.ActionLink("Admin only link", "ActionName", "ControllerName")
    @Html.ActionLink("Another admin link", "ActionName", "ControllerName")
}

If it is from a specific action method, you can specify a layout:

string layoutName = Roles.IsUserInRole("GlobalAdmin") ? "_LayoutAdmin" : "_Layout";
return View(model, layoutName);

You can automate this last method by using a custom actionresult or maybe even an action filter.

c# - how to load a different _layout.cshtml depending on role? - Stack...

c# asp.net-mvc asp.net-mvc-4 razor
Rectangle 27 5

You'd better create a new area, the controllers, views, models, and such folders will be created for you automaticaly.

razor - How do I create views and controllers folders in ASP.NET MVC 3...

asp.net-mvc-3 razor
Rectangle 27 0

As @Antony Teisserie mentioned do create an area name "Admin" so that you can access the admin panel via "your_url.tld/Admin"

razor - How do I create views and controllers folders in ASP.NET MVC 3...

asp.net-mvc-3 razor
Rectangle 27 0

With the info you provide I can think of extending the helper NavLink in one of two way:

  • Add a parameter for passing user's role
  • Passing only a parameter of type class/interface containing all the fields your method needs

Would it be possible to pass the user into the helper and if I did that then could I still do an IsInRole check from there?

Why not. If you pass the instance of the user you should be able to call User.IsInRole as you do outside the helper

asp.net mvc - How can I pass a parameter based on if the user is in a ...

asp.net-mvc asp.net-mvc-3 razor