Found a typo or error? Suggest an edit! If accepted, your contribution is listed automatically here.

Comments

avatar

43 responses

  1. Avatar for Anthony Bouch
    Anthony Bouch January 17th, 2010

    Cool, but why would you take this approach over attempting to use an XML file that can be used to create routes declaratively and then making this part of the bootstrap process for the app? More work I guess?

  2. Avatar for Vijay Santhanam
    Vijay Santhanam January 17th, 2010

    NICE!! I tried to write something similar for configurable rules that required some code. They were ShopCartPromotions that needed to be added and removed without a redeploy.
    I couldn't figure out how to have non-pre-compiled .cs - but you did it!
    I ended up with an uber xml config file that was linked to the web.config. when the rules.config changed, the app rebooted and reloaded the config. I wrote waaay too much code to generalize for all possible ShopCartPromotions. Your solution would've been great about 2 months ago...
    now can you write a visual studio plugin to jump back in time?

  3. Avatar for Aleš Roubíček
    Aleš Roubíček January 17th, 2010

    I have on my project routes in Global Resource file, so they are editable after deployment and are localizable (one language per web instance). I also use Binsor and my own Routes DSL.

  4. Avatar for Aleš Roubíček
    Aleš Roubíček January 17th, 2010

    BTW why don't are you using App_Code folder? It has IMO same functionality. :)

  5. Avatar for Dhananjay Goyani
    Dhananjay Goyani January 17th, 2010

    Nice work. On one hand this gives lot of flexibility to dev over xml based configuration, however on the other side, allowing code injection like this can be harmful in un-controlled environment.

  6. Avatar for paul
    paul January 17th, 2010

    Nice article, Phil.
    My team ran into this use case a while back (iirc it was shortly before the 1.0 RTM) and we considered a number of approaches, including something similar to this one (though, like Alec commented above, we were looking at the App_Code directory to solve the file watching for us)
    We didn't use XML because we felt it wasn't flexible enough to cover all the routing scenarios
    We didn't use the code-generating approach (e.g. thsi one or the App_Code solution) because we felt like it would be too easy to break the app, and too hard to fix it once deployed if the app was so broken.
    What we ended up going with was to create a route serializer class, which would actually serialize teh route values along with some metadata, and the logic that updated it would also save teh changes to the db and ensure that the two representations were kept in sync.
    Paul

  7. Avatar for Dan F
    Dan F January 17th, 2010

    P'rhaps a silly question, but is this web site, web app, or both?

  8. Avatar for Ira
    Ira January 17th, 2010

    Very cool post Phil. I like the no xml configuration!

  9. Avatar for Leniel Macaferi
    Leniel Macaferi January 17th, 2010

    Phil,
    I really liked the new point of view of this implementation.
    This same path can be used to do a lot of things!
    It's so good to be able to do things like that, I mean, the language and the framework has so many features that enable us to do amazing things in a few lines of code. This is developer power... or better yet, power on developer hands...
    To monitor a file on disk and recompile the code generating a new assembly dynamically. Fantastic! :)
    Thanks for showing us how to do that,
    Leniel Macaferi

  10. Avatar for haacked
    haacked January 17th, 2010

    @DanF at runtime, there's no difference between WAP and website. But this is a WAP.

  11. Avatar for haacked
    haacked January 17th, 2010

    Also, another way to accomplish this scenario is to define routes using a dynamic language. If you'd prefer to use Ruby (ironruby actually) to define routes, I showed how to do that a long time ago. haacked.com/...

  12. Avatar for Adam
    Adam January 17th, 2010

    Depending on the size of your site and the amount of traffic you handle, you would want to avoid making your system rely on the App_Code automatic recompile. As confirmed in the MSDN article on dynamic compilation, you would cause a full-site recompile (assuming you haven't tweaked the config settings for it and don't mind those side-effects, ibid). If your site is under any sort of load, that would cause problems for your users while it happens. The approach Phil takes would have a much smaller impact on things.

  13. Avatar for haacked
    haacked January 17th, 2010

    @Aleš I could have used the App_Code folder and called BuildManager.GetType("Routes") and that would have worked too.
    As Adam points out, that would cause a full AppDomain and Views recycle when you change a route. I wanted to avoid that. It does have the benefit that I don't have to manage my own file monitoring, which is a big benefit. :)

  14. Avatar for YP
    YP January 17th, 2010

    Good blog entry, I believe Phil you have used this approach before in one of your blog.
    using the buildManager approach!!!
    Thanks,
    YP

  15. Avatar for Koistya `Navin
    Koistya `Navin January 17th, 2010

    I would personally avoid this design, there are better ways to archieve the same end result with less trade-offs (like for example storing routes in .xml files or database and reloading routes if necessary without application restart).

  16. Avatar for Paco
    Paco January 18th, 2010

    Changing properties of the applications without needing to recompile only has is useful when you don't need a programmer. To configure the routes, you need to know how the controller code looks like, so you probably need a programmer to change the routes like this. This cannot be done by a system administrator. When you need a programmer to make changes, why won't you just deploy a new dll?

  17. Avatar for haacked
    haacked January 18th, 2010

    I've updated this post so it works in Medium Trust.

  18. Avatar for Aleš Roubíček
    Aleš Roubíček January 18th, 2010

    @Adam in this case you never can deploy new version of your site, cos your App poll will recycle. On hevy load apps, there is a balancer. On hevy load apps there is no unscheduled staging. There is no need to worry about it. App_Code is just fine. :)

  19. Avatar for Harry M
    Harry M January 18th, 2010

    Hope you're escaping the routes people are giving you at runtime... c# script injection could be a scary thing.

  20. Avatar for Travis Illig
    Travis Illig January 18th, 2010

    Correct me if I'm wrong, but I think you may have a tiny memory leak doing it this way.
    Assemblies loaded into an AppDomain can't be unloaded without tearing down the whole AppDomain. If you're rebuilding a new tiny temporary assembly each time the code changes, the old tiny temporary assembly with the old code still exists in the AppDomain.
    I think I'd go with the App_Code for specifying in code. You eat the restart but there's no memory leak. (I suppose you could craft your solution to build the temporary assembly into a separate AppDomain and marshal the object over, but that sounds like so much work.)
    For XML config you could use a CacheDependency with a file dependency and set up a callback to let you know when the config changes. I think CacheDependencies work correctly in medium trust and will correctly monitor the file just like a FileSystemWatcher would. (I haven't tested, though...)

  21. Avatar for haacked
    haacked January 19th, 2010

    @Harry, this is still based on code being deployed to your web server. I wouldn't let random people deploy code to my webserver. :)
    @Travis that's a good point. I think in general, the number of times someone changes routes in the lifetime of the app will be very small.

  22. Avatar for Sam
    Sam January 21st, 2010

    Hi All ,
    i am getting the below error , can any one help me out why its not working , i downloaded sample project try to run but it will give me this below error.

    Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.

  23. Avatar for Imran Baloch
    Imran Baloch January 24th, 2010

    Why not use global.asax of one which we used in WebSites(not Web Projects)

  24. Avatar for Nathan Taylor
    Nathan Taylor January 26th, 2010

    I too am receiving 404 errors from the sample (and also after implementing the code myself).
    Any advice on how to make this work with area registration as well?

  25. Avatar for Jon  Ranes
    Jon Ranes February 16th, 2010

    I see what you are doing, nice. I was really hoping that I could just add a single route or edit a single route at runtime in MVC 2. We are still tearing all the routes down and rebuilding them here.
    Just out of interest what is the big drawback or holdup to editing or adding or removing a single route by reference at runtime?
    In an average CMS there would probably be only one or two times a day that new routes needed to be introduced so for now I am sticking with popping the web.config to trigger app_restart.
    I'll keep my eye on this method though. I build most of my routes from the database and when I need to change one I pop the web.config.

  26. Avatar for Jon  Ranes
    Jon Ranes February 17th, 2010

    I have found with the code below I can edit or delete a route at runtime perfectly. It is just adding new routes that won't work this way. Sure would be nice to have.

    public static void TestChangeRouteRuntime(RouteCollection routes)
    {
    var routesToRemove = new List<RouteBase>();
    foreach (var routeBase in routes)
    {
    var route = routeBase as Route;
    if (route.Url == "cms/{*path}")
    {
    route.Url = "cms2/{*path}";
    routesToRemove.Add(routeBase);
    }
    }
    foreach (var routeToRemove in routesToRemove)
    {
    routes.Remove(routeToRemove);
    }
    }

  27. Avatar for Jon  Ranes
    Jon Ranes February 17th, 2010

    Maybe someday we can see the System.Web.Routing source?

  28. Avatar for SEOINK&#195;ƒ&#198;’&#195;&#16
    SEOINK&#195;ƒ&#198;’&#195;&#16 March 8th, 2010

    weiter so

  29. Avatar for Marcus
    Marcus March 10th, 2010

    I am receiving 404 errors when I try to run the sample as well. I think the Routes.cs file is erroring out during the dynamic compile process. Any suggestions?

  30. Avatar for bigsan
    bigsan February 13th, 2011

    calling RouteTable.Routes.RegisterRoutes("~/...") in Application_Start is not enough, because it won't call the ReloadRoutes() at the first time while the file is not changed.
    ReloadRoutes() should be called after Listen() in RegisterRoutes(), doesn't it?
    (sorry for the wrong post in "ASP.NET Route Debugger")

  31. Avatar for haacked
    haacked February 14th, 2011

    @bigsan I think you may be correct. I'll have to look at it.

  32. Avatar for ASP.NET MVC DEVELOPER
    ASP.NET MVC DEVELOPER May 14th, 2011

    Leading experts in PHP Website Developer, ASP.NET, Open Source Customization, Ecommerce, iPhone Development, Andriod, Mobile and Social application development. Consult us for all of your Web Application needs! PHP Development

  33. Avatar for Dave
    Dave November 16th, 2011

    Any suggestions for unit testing Routes.cs? I would still like to unit test my routes.

  34. Avatar for Sean
    Sean April 17th, 2013

    Here is a question. What exactly is in the RouteMagic dll, and do I still need to implement the code outlined in this post with RouteMagic installed?

    I'm unclear as to what installing RouteMagic did for me.

  35. Avatar for haacked
    haacked April 17th, 2013

    Could you log an issue here?

    https://github.com/Haacked/...

  36. Avatar for Sean
    Sean April 17th, 2013

    I could. This isn't necessarily an issue with your code as an issue with my grokking this RouteMagic pkg.

  37. Avatar for haacked
    haacked April 17th, 2013

    I beg to differ. If the package is hard to use, then it's a problem with my project! And I want to help you not only grok it, but figure out how I can make it more grokkable. :)

  38. Avatar for Abhijeet
    Abhijeet February 5th, 2015

    @haacked: I'm doing something similar to generate an assembly on the fly and add it to the BuildManager by calling AddReferencedAssembly but am running into issues.
    I've posted this on SO but haven't received any proper responses and was wondering if you could take a look.

    http://stackoverflow.com/qu...

  39. Avatar for Googy
    Googy March 8th, 2015

    I'm writing an MVC 5 app, do I want RouteMagic, RouteMagic.MVC or both, confused here?

  40. Avatar for Googy
    Googy March 8th, 2015

    Too bad, the code in the samples above no longer match the NuGet package and wont compile, there is no RouteTable.Routes.RegisterRoutes() method anymore, not sure what to do now, really needed this too

  41. Avatar for Googy
    Googy March 8th, 2015

    Nevermind, got it, needed both the RouteMagic and RouteMagic.MVC and got my fake VanityURL stuff working in 5 minutes. You sir, are a genius ...

  42. Avatar for WINDFISH
    WINDFISH May 22nd, 2015

    Due to legacy reason, my website has WebAPI attribute routes, MVC routes and many customized routes (Added on app_start). The customized routes should be updated periodically based on a list provided outside this system. Therefore I cannot do RouteTable.Routes.Clear() to clear all the routes. Do you have any suggestion if I only want to update partial of my routing tables?

  43. Avatar for ozzy
    ozzy April 25th, 2017

    Anyone still using this? Using VS2015 now with ASP.NET MVC 5. I downloaded the Nugets, etc but asp.net doesnt like this //RouteTable.Routes.RegisterRoutes("~/Config/Routes.cs"); in global.asax.cs I assume its just something to do with the fact im using a newer version. This topic has been quiet for a while. Is there now an accepted solution to this problem in asp.net MVC?