Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enumerating ASP.NET MVC RouteTable route URLs

I'm trying to figure out how to enumerate the URLs of Routes in the RouteTable.

In my scenario, I have the following routes defined:

routes.MapRoute
  ("PadCreateNote", "create", new { controller = "Pad", action = "CreateNote" });
routes.MapRoute
  ("PadDeleteNote", "delete", new { controller = "Pad", action = "DeleteNote" });
routes.MapRoute
   ("PadUserIndex", "{username}", new { controller = "Pad", action = "Index" });

In other words, if my site is mysite.com, mysite.com/create invokes PadController.CreateNote(), and mysite.com/foobaris invokes PadController.Index().

I also have a class that strongly types usernames:

public class Username
{
    public readonly string value;

    public Username(string name)
    {
        if (String.IsNullOrWhiteSpace(name)) 
        {
            throw new ArgumentException
                ("Is null or contains only whitespace.", "name");
        }

        //... make sure 'name' isn't a route URL off root like 'create', 'delete'

       this.value = name.Trim();
    }

    public override string ToString() 
    {
        return this.value;
    }
}

In the constructor for Username, I would like to check to make sure that name isn't a defined route. For example, if this is called:

var username = new Username("create");

Then an exception should be thrown. What do I need to replace //... make sure 'name' isn't a route URL off root with?

like image 935
AgileMeansDoAsLittleAsPossible Avatar asked Dec 14 '10 18:12

AgileMeansDoAsLittleAsPossible


1 Answers

This doesn't fully answer what you are wanting to do by preventing users from registering protected words, but there is a way you can constrain your routes. We had /username url's in our site and we used a constraint like so.

routes.MapRoute(
                "Default",                                              // Route name
                "{controller}/{action}/{id}",                           // URL with parameters
                new { controller = "Home", action = "Index", id = "" },   // Parameter defaults
                new
                {
                    controller = new FromValuesListConstraint(true, "Account", "Home", "SignIn" 
                        //...etc
                    )
                }
            );

routes.MapRoute(
                 "UserNameRouting",
                  "{id}",
                    new { controller = "Profile", action = "Index", id = "" });

You may just have to keep a list of reserved words, or, if you really want it automatic, you could possibly use reflection to get a list of the controllers in the namespace.

You can access the route collection with this. The issue with this approach is that it requires you to explicitly register all routes you want to be "protected". I still hold to my statement you'd be better off having a list of reserved keywords stored elsewhere.

System.Web.Routing.RouteCollection routeCollection = System.Web.Routing.RouteTable.Routes;


var routes = from r in routeCollection
             let t = (System.Web.Routing.Route)r
             where t.Url.Equals(name, StringComparison.OrdinalIgnoreCase)
             select t;

bool isProtected = routes.Count() > 0;
like image 51
Josh Avatar answered Oct 18 '22 05:10

Josh