views:

142

answers:

4

For my administration area I have created a special route. I did this so my urls look cleaner, and it avoids the problem of me having 2 controllers with the same name.

Example: I have a UserController and another AdminUserController for the admin site of the application.

I don't want URL's like:

http://www.example.com/user/...
http://www.example.com/admin/adminuser/...

I want the admin url's to look like:

http://www.example.com/admin/user/...

Now to get this url structure, I tried this:

I named my admin controller: AdminUserController

Then my route looks like:

routes.Add(new Route("admin/Admin{controller}/{action}/{id}", new MvcRouteHandler())
{
  Defaults = new RouteValueDictionary(new { controller = "Admin", action = "index", Id=""});
});

Can this work? (the route is currently not working)

I made sure to have this route above the generic route.

Update

I want all my admin urls to be prefixed with the /admin/ folder, so:

www.example.com/admin/user
www.example.com/admin/settings
www.example.com/admin/articles

and non-admin are like:

www.example.com/user
www.example.com/articles
+3  A: 

No, that won't work.

Keep in mind that we append "Controller" to the URL part passed in for {controller}. Thus the URL that would work there is:

/admin/AdminAdminUser/

Try this instead.

routes.Add(new Route("admin/user/admin/{action}/{id}", new MvcRouteHandler())
{
  Defaults = new RouteValueDictionary(new { controller = "AdminUser", action = "index", Id=""})
});

I'm assuming the AdminUser controller is a special case and you don't have other controllers that start with /user/. If you did, an alternate approach is to rename AdminUserController back to AdminController. Then:

routes.Add(new Route("admin/user/{controller}/{action}/{id}", new MvcRouteHandler())
{
  Defaults = new RouteValueDictionary(new { controller = "Admin", action = "index", Id=""}),
  Constraints = new RouteValueDictionary(new { controller = "Admin|Other|Other2"})
});

Here i'm using a constraint to limit which controllers this particular route applies to.

BTW, I'd recommend using the MapRoute extension methods. They make for much less verbose route registration.

Haacked
I want www.example.com/admin/user and www.example.com/user to work. One controller is AdminUserController and UserController. is that what you responded too? becaues your 2nd route is admin/user/{controller}... I have many admin controllers, so I don't want to hardcode. thanks!
mrblah
+3  A: 
routes.Add(new Route("admin/Admin{controller}/{action}/{id}", new MvcRouteHandler())
{
  Defaults = new RouteValueDictionary(new { controller = "Admin", action = "index", Id=""});
});

will force you to have "admin/AdminUser" ...

 routes.MapRoute(
                "Default",                                              // Route name
                "admin/{action}/{id}",                           // URL with parameters
            new { controller = "Admin", action = "User", id = "" }  // Parameter defaults
        );

will allow you to have an admin controller with an action User


More accurately what you are looking to do is create an area (use MVC 2)

http://odetocode.com/Blogs/scott/archive/2009/10/13/asp-net-mvc2-preview-2-areas-and-routes.aspx

should give you what you want...

Hurricanepkt
crap... so muuch for an eaasy answer ... I haave been officially haacked...
Hurricanepkt
isn't this what I have now??
mrblah
you have admin/Admin{controller}which which means two admins before it starts to find the controller name
Hurricanepkt
hmm, but I want a UserController and a AdminUserController (I will also have other AdminXXXController's).
mrblah
you want all the admin controllers to start /admin/ ??
Hurricanepkt
see my update please, thanks!
mrblah
A: 

With 1.0 the only way to do this is :

Using 1.0 the only way to do this is to map each controller individually using

   routes.MapRoute(
            "AdminUserRoute",                     // Route name
            "admin/user/{action}/{id}",           // URL with parameters
        new { controller = "AdminUser", action = "Index", id = "" } 
    );

   routes.MapRoute(
            "AdminWorkRoute",                    // Route name
            "admin/work/{action}/{id}",          // URL with parameters
        new { controller = "AdminWork", action = "Index", id = "" }                
    );
Hurricanepkt
A: 

Create an implementation of IRouteHandler that will intercept the requested controller and append "admin" to the front

public class AdminRouteHandler : IRouteHandler
{
    private readonly IRouteHandler _mvcHandler = new MvcRouteHandler();
    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        var values = requestContext.RouteData.Values;
        if(values.ContainsKey("controller"))
            values["controller"] = "Admin" + values["controller"];
        return _mvcHandler.GetHttpHandler(requestContext);
    }
}

And use that when registering your route, replacing Home with whatever controller that admin/ should direct you to. Leaving Home in default would map to AdminHome after passing through the AdminRouteHandler.

routes.Add(new Route("admin/{controller}/{action}/{id}", new AdminRouteHandler())
{
  Defaults = new RouteValueDictionary(new { controller = "Home", action = "index",     Id=""});
});
statenjason