title: .NET MVC2 custom subpage routes
body: <p>In searching I came across <a href="https://stackoverflow.com/questions/411054/asp-net-mvc-page-subpage-routing">ASP.NET MVC page/subpage routing</a> and the wildcard was somewhat of a lifesaver, but presented a new problem.</p>
  
  <p>Consider the following routes, if you will. The goal here is to have the index (<em><a href="http://www.domain.com" rel="nofollow noreferrer">http://www.domain.com</a></em>) use the default route and <em>[domain]/page</em> use the <strong>Content</strong> route. The strSlug is a wildcard because I plan on splitting the slug to use for subpages. <em>[domain]page/subpage</em> (subpage would be the current slug). With it being a wildcard, it seems like [domain] is matching on the <strong>Content</strong> route.</p>
  
  <p>What would be the proper way around that?</p>
  
  <pre><code>// Global.asx.cs  
  routes.MapRoute(
          "Content", // Route name
          "{*strSlug}", // URL with parameters
          new { controller = "Home", action = "SiteContent", strSlug = UrlParameter.Optional } // Parameter defaults
      );
  
      routes.MapRoute(
          "Default", // Route name
          "{controller}/{action}", // URL with parameters
          new { controller = "Home", action = "Index" } // Parameter defaults
      );
  
      // HomeController.cs
      // Not the best code, feel free to improve.
      public ActionResult SiteContent(string strSlug)
      {
          string[] strSlug_arr = strSlug.Split("/".ToCharArray());
          strSlug = strSlug_arr[(strSlug_arr.Length-1)];
  
          SiteContent data = DB.SiteContents.Single(c =&gt; c.Slug == strSlug);
          return View(data);
      }
  </code></pre>
  
  <p>EDIT:
  In doing some more research, I was hoping to use something like this.</p>
  
  <pre><code>public ActionResult Index()
  {
      SiteContent data = DB.SiteContents.Single(c =&gt; c.Slug == "home-page");
      return View(data);
  }
  
  public ActionResult SiteContent(string strSlug)
  {
      if (strSlug == null)
      {
          return RedirectToAction("Index");
      }
      else
      {
          string[] strSlug_arr = strSlug.Split("/".ToCharArray());
          strSlug = strSlug_arr[(strSlug_arr.Length - 1)];
  
          SiteContent data = DB.SiteContents.Single(c =&gt; c.Slug == strSlug);
          return View(data);
      }
  }
  </code></pre>
  
  <p>..but this results in a redirect loop for some reason.</p>
  
  <p>EDIT #2
  So this solution kind of, sort of, maybe works? I have yet to see a downside.</p>
  
  <pre><code>    // Global.asx.cs
      routes.MapRoute(
          "Content", // Route name
          "{strSlug}/{*strSubSlug}", // URL with parameters
          new { controller = "Home", action = "SiteContent", strSubSlug = UrlParameter.Optional } // Parameter defaults
      );
  
      routes.MapRoute(
          "Default", // Route name
          "{controller}/{action}/", // URL with parameters
          new { controller = "Home", action = "Index" } // Parameter defaults
      );
  
  
      // HomeController.cs
      public ActionResult Index()
      {
          SiteContent data = DB.SiteContents.Single(c =&gt; c.Slug == "home-page");
          return View(data);
      }
  
      public ActionResult SiteContent(string strSlug, string strSubSlug)
      {
          /*
          string[] strSlug_arr = strSlug.Split("/".ToCharArray());
          strSlug = strSlug_arr[(strSlug_arr.Length - 1)];
           */
  
          if (strSubSlug != null)
          {
              string[] strSubSlug_arr = strSubSlug.Split("/".ToCharArray());
              strSlug = strSubSlug_arr[(strSubSlug_arr.Length - 1)];
          }
  
          SiteContent data = DB.SiteContents.Single(c =&gt; c.Slug == strSlug);
          return View(data);
      }
  </code></pre>
  
  <p>So [domain]/slug works.. and anything after that it parses off the last slug.. so [domain]slug/sub/sub/sub/content would grab the page matching the content slug.</p>