Click here to Skip to main content
15,895,011 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
In my application I am working with different user roles, based on role I am redirecting user to to controllers.

Now I want to add route prefix based on roles as below

If logined user role is Admin then The URL should be:

http://localhost:/Admin/Home/Index[^]


If Logined user role is 'User' then the URL Should be

http://localhost:/User/Home/Index[^]


How to add these custom route prefixes based on roles in mvc


Thanks In Advance

What I have tried:

On controller I Have added
[RoutePrefix("Admin/User")]
Its not working I want to add this prefix based on roles.

[CustomAuthorize("User", "Admin")]
[RoutePrefix("Admin/User")]
public class HomeController : SecureController
{
public actionresult Index()
{
return view();
}
}


here If user role is admin then prefix should come as http://localhost:/Admin/Home/Index[^]
Posted
Updated 18-Mar-20 4:31am
v3

There's no real value in doing this, if you want to know the user role then get the role when you need to know it, taking it from the url is a security issue. If you just want it on the url for aesthetics then something like this might help

Create a route handler

C#
public class UserRoleHandler : IRouteHandler
{
    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        // Work out the role here, I am hard-coding for simplicity
        string userRole = "Admin";

        requestContext.RouteData.Values["role"] = userRole;

        return new MvcHandler(requestContext);
    }
}


and update your default route mapping as follows

C#
routes.MapRoute(
    name: "Default",
    url: "{role}/{controller}/{action}/{id}",
    defaults: new { role = "User", controller = "Home", action = "Index", id = UrlParameter.Optional }
).RouteHandler = new UserRoleHandler();


We've put the role parameter first, but the custom UserRoleHandler will ensure the role value is whatever role the user is in rather than what is on the url. So even if someone manually changes "User" to "Admin" the role value will still be User if that's what they are.

The above is MVC 5, you might need to adjust as necessary if you're not using 5.

Update

The original route won't work with this config, if you want the traditional "controller/action" route to work you might want to try something like

C#
routes.MapRoute(
    name: "Default",
    url: "Account/{role}/{controller}/{action}/{id}",
    defaults: new { role = "User", controller = "Home", action = "Index", id = UrlParameter.Optional }
).RouteHandler = new UserRoleHandler();

routes.MapRoute(
    name: "Traditional",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);


The issue with multiple routes like above is that when generating urls if you want to specifically have the standard url pattern you need to specify you want to use the "Traditional" route. The alternative is that you leave the default as it is and use the one with the role as the non-default, but then any time you want a url in that format you'll need to choose the relevant route name when generating it.
 
Share this answer
 
v2
Comments
Divyay208 16-Mar-20 16:49pm    
Thanks for the solution, but Roles we get once the user logins, from the above solution 'UserRoleHandler' class getting called way before the Custom Authorize class from filters execution, So I am not getting any roles to implement the above solution
F-ES Sitecore 16-Mar-20 17:37pm    
Your users have roles regardless of if Authorise has been called yet. That just denies access to the action if the user isn't in the right role, it doesn't actually assign the role. Google how to get a list of roles a user is in.
Divyay208 16-Mar-20 22:38pm    
I have Implemented the same but I am getting errors in
public class UserRoleHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
// Work out the role here, I am hard-coding for simplicity
var listRoles = new List<string> { "Admin", "User", "RRR" };

requestContext.RouteData.Values["role"] = listRoles;

return new MvcHandler(requestContext);
}
}

The error is 'The controller for path '/Home/Index' was not found or does not implement IController.'
F-ES Sitecore 17-Mar-20 6:53am    
I've updated the original solution
Divyay208 17-Mar-20 14:13pm    
Thanks for the solution, I modified my code accordingly still it's not working, May be It won't work this way, I updated what I have tried in question. my requirement is similar to https://stackoverflow.com/questions/32764989/asp-net-mvc-5-culture-in-route-and-url

but this is based on current culture.
I have done the URL rewriting as below and I am able add this prefix for every controller.

Add below in authorization filter

public override void OnAuthorization(AuthorizationContext filterContext)
       {
           var userRoleName = //GetUserRoleName;

           filterContext.RouteData.Values["role"] = userRoleName;
       }


Then we can simply add Routeprefix on controller level after authorizing user role
[CustomAuthorize("Admin", "User")]
   [RoutePrefix("{role}")]
   public class HomeController : Controller
   {
   [Route]
   public ActionResult Index()
   {
   return View()
   }
   }
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900