<p>Python frameworks always provide ways to handle URLs that convey the data of the request in an elegant way, like for example <a href="http://somewhere.overtherainbow.com/userid/123424/" rel="noreferrer">http://somewhere.overtherainbow.com/userid/123424/</a></p>

<p>I want you to notice the ending path <strong>/userid/123424/</strong></p>

<p>How do you do this in ASP.NET?</p>

[{'answer_id': 45347, 'author': 'John Sheehan', 'author_id': 1786, 'author_profile': 'https://Stackoverflow.com/users/1786', 'pm_score': 0, 'selected': False, 'text': "<p>Also, check out ASP.NET MVC or if you're set on webforms, the new System.Web.Routing namespace in ASP.NET 3.5 SP1</p>\n"}, {'answer_id': 406947, 'author': 'Dominic Betts', 'author_id': 50911, 'author_profile': 'https://Stackoverflow.com/users/50911', 'pm_score': 5, 'selected': False, 'text': '<p>This example uses ASP.NET Routing to implement friendly URLs.  </p>\n\n<p>Examples of the mappings that the application handles are:  </p>\n\n<p><a href="http://samplesite/userid/1234" rel="noreferrer">http://samplesite/userid/1234</a> - <a href="http://samplesite/users.aspx?userid=1234" rel="noreferrer">http://samplesite/users.aspx?userid=1234</a><br>\n<a href="http://samplesite/userid/1235" rel="noreferrer">http://samplesite/userid/1235</a> - <a href="http://samplesite/users.aspx?userid=1235" rel="noreferrer">http://samplesite/users.aspx?userid=1235</a>  </p>\n\n<p>This example uses querystrings and avoids any requirement to modify the code on the aspx page.  </p>\n\n<h1>Step 1 - add the necessary entries to web.config</h1>\n\n<pre><code>&lt;system.web&gt;\n&lt;compilation debug="true"&gt;\n        &lt;assemblies&gt;\n            …\n            &lt;add assembly="System.Web.Routing, Version=3.5.0.0,    Culture=neutral, PublicKeyToken=31BF3856AD364E35"/&gt;\n        &lt;/assemblies&gt;\n    &lt;/compilation&gt;\n…\n    &lt;httpModules&gt;\n    …\n        &lt;add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /&gt;\n        &lt;/httpModules&gt;\n&lt;/system.web&gt;\n&lt;system.webServer&gt;\n    …\n    &lt;modules&gt;\n        …\n        &lt;add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/&gt;\n    &lt;/modules&gt;\n    &lt;handlers\n…   \n        &lt;add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler,                 System.Web, Version=2.0.0.0, Culture=neutral,              PublicKeyToken=b03f5f7f11d50a3a"/&gt;\n    &lt;/handlers&gt;\n&lt;/system.webServer&gt;\n</code></pre>\n\n<h1>Step 2 - add a routing table in global.asax</h1>\n\n<p>Define the mapping from the friendly URL to the aspx page, saving the requested userid for later use.  </p>\n\n<pre><code>void Application_Start(object sender, EventArgs e)\n{\n    RegisterRoutes(RouteTable.Routes);\n}\n\npublic static void RegisterRoutes(RouteCollection routes)\n{\n    routes.Add("UseridRoute", new Route\n    (\n       "userid/{userid}",\n       new CustomRouteHandler("~/users.aspx")\n    ));\n}\n</code></pre>\n\n<h1>Step 3 - implement the route handler</h1>\n\n<p>Add the querystring to the current context before the routing takes place.  </p>\n\n<pre><code>using System.Web.Compilation;\nusing System.Web.UI;\nusing System.Web;\nusing System.Web.Routing;\n\npublic class CustomRouteHandler : IRouteHandler\n{\n    public CustomRouteHandler(string virtualPath)\n    {\n        this.VirtualPath = virtualPath;\n    }\n\n    public string VirtualPath { get; private set; }\n\n    public IHttpHandler GetHttpHandler(RequestContext\n          requestContext)\n    {\n        // Add the querystring to the URL in the current context\n        string queryString = "?userid=" + requestContext.RouteData.Values["userid"];\n        HttpContext.Current.RewritePath(\n          string.Concat(\n          VirtualPath,\n          queryString)); \n\n        var page = BuildManager.CreateInstanceFromVirtualPath\n             (VirtualPath, typeof(Page)) as IHttpHandler;\n        return page;\n    }\n}\n</code></pre>\n\n<h1>Code from users.aspx</h1>\n\n<p>The code on the aspx page for reference.  </p>\n\n<pre><code>protected void Page_Load(object sender, EventArgs e)\n{\n    string id = Page.Request.QueryString["userid"];\n    switch (id)\n    {\n        case "1234":\n            lblUserId.Text = id;\n            lblUserName.Text = "Bill";\n            break;\n        case "1235":\n            lblUserId.Text = id;\n            lblUserName.Text = "Claire";\n            break;\n        case "1236":\n            lblUserId.Text = id;\n            lblUserName.Text = "David";\n            break;\n        default:\n            lblUserId.Text = "0000";\n            lblUserName.Text = "Unknown";\n            break;\n}\n</code></pre>\n'}, {'answer_id': 407017, 'author': 'Dominic Betts', 'author_id': 50911, 'author_profile': 'https://Stackoverflow.com/users/50911', 'pm_score': 3, 'selected': False, 'text': '<p>This is an alternative example that also uses ASP.NET Routing to implement friendly URLs.  </p>\n\n<p>Examples of the mappings that the application handles are:  </p>\n\n<p><a href="http://samplesite/userid/1234" rel="noreferrer">http://samplesite/userid/1234</a> - <a href="http://samplesite/users.aspx?userid=1234" rel="noreferrer">http://samplesite/users.aspx?userid=1234</a><br>\n<a href="http://samplesite/userid/1235" rel="noreferrer">http://samplesite/userid/1235</a> - <a href="http://samplesite/users.aspx?userid=1235" rel="noreferrer">http://samplesite/users.aspx?userid=1235</a>  </p>\n\n<p>This example <strong>does not</strong> use querystrings but <strong>requires additional code</strong> on the aspx page.  </p>\n\n<h1>Step 1 - add the necessary entries to web.config</h1>\n\n<pre><code>&lt;system.web&gt;\n&lt;compilation debug="true"&gt;\n        &lt;assemblies&gt;\n            …\n            &lt;add assembly="System.Web.Routing, Version=3.5.0.0,    Culture=neutral, PublicKeyToken=31BF3856AD364E35"/&gt;\n        &lt;/assemblies&gt;\n    &lt;/compilation&gt;\n…\n    &lt;httpModules&gt;\n    …\n        &lt;add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /&gt;\n        &lt;/httpModules&gt;\n&lt;/system.web&gt;\n&lt;system.webServer&gt;\n    …\n    &lt;modules&gt;\n        …\n        &lt;add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/&gt;\n    &lt;/modules&gt;\n    &lt;handlers\n…   \n        &lt;add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler,                 System.Web, Version=2.0.0.0, Culture=neutral,              PublicKeyToken=b03f5f7f11d50a3a"/&gt;\n    &lt;/handlers&gt;\n&lt;/system.webServer&gt;\n</code></pre>\n\n<h1>Step 2 - add a routing table in global.asax</h1>\n\n<p>Define the mapping from the friendly URL to the aspx page, saving the requested userid for later use.  </p>\n\n<pre><code>void Application_Start(object sender, EventArgs e)\n{\n    RegisterRoutes(RouteTable.Routes);\n}\n\npublic static void RegisterRoutes(RouteCollection routes)\n{\n    routes.Add("UseridRoute", new Route\n    (\n       "userid/{userid}",\n       new CustomRouteHandler("~/users.aspx")\n    ));\n}\n</code></pre>\n\n<h1>Step 3 - implement the route handler</h1>\n\n<p>Pass the routing context, containing the parameter, to the page. (Note the definition of IRoutablePage)  </p>\n\n<pre><code>using System.Web.Compilation;\nusing System.Web.UI;\nusing System.Web;\nusing System.Web.Routing;\n\npublic interface IRoutablePage\n{\n    RequestContext RequestContext { set; }\n}\n\npublic class CustomRouteHandler : IRouteHandler\n{\n    public CustomRouteHandler(string virtualPath)\n    {\n        this.VirtualPath = virtualPath;\n    }\n\n    public string VirtualPath { get; private set; }\n\n    public IHttpHandler GetHttpHandler(RequestContext\n          requestContext)\n    {\n        var page = BuildManager.CreateInstanceFromVirtualPath\n             (VirtualPath, typeof(Page)) as IHttpHandler;\n\n        if (page != null)\n        {\n            var routablePage = page as IRoutablePage;\n\n            if (routablePage != null) routablePage.RequestContext = requestContext;\n        }\n\n        return page;\n    }\n}\n</code></pre>\n\n<h1>Step 4 - Retrieve the parameter on the target page</h1>\n\n<p>Note the implemetation of IRoutablePage.  </p>\n\n<pre><code>using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Web;\nusing System.Web.UI;\nusing System.Web.UI.WebControls;\nusing System.Web.Routing;\n\npublic partial class users : System.Web.UI.Page, IRoutablePage\n{\n    protected RequestContext requestContext;\n\n    protected object RouteValue(string key)\n    {\n        return requestContext.RouteData.Values[key];\n    }\n\n    protected void Page_Load(object sender, EventArgs e)\n    {\n        string id = RouteValue("userid").ToString();\n        switch (id)\n        {\n            case "1234":\n                lblUserId.Text = id;\n                lblUserName.Text = "Bill";\n                break;\n            case "1235":\n                lblUserId.Text = id;\n                lblUserName.Text = "Claire";\n                break;\n            case "1236":\n                lblUserId.Text = id;\n                lblUserName.Text = "David";\n                break;\n            default:\n                lblUserId.Text = "0000";\n                lblUserName.Text = "Unknown";\n                break;\n        }\n    }\n\n    #region IRoutablePage Members\n\n    public RequestContext RequestContext\n    {\n        set { requestContext = value; }\n    }\n\n    #endregion\n}\n</code></pre>\n'}, {'answer_id': 413442, 'author': 'Dominic Betts', 'author_id': 50911, 'author_profile': 'https://Stackoverflow.com/users/50911', 'pm_score': 1, 'selected': False, 'text': '<h3>Here\'s another way of doing it using ASP.NET MVC</h3>\n\n<p>First off, here\'s the controller code with two actions. Index gets a list of users from the model, userid gets an individual user:  </p>\n\n<pre><code>using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Web;\nusing System.Web.Mvc;\nusing System.Web.Mvc.Ajax;\n\nnamespace MvcApplication1.Controllers\n{\n    public class UsersController : Controller\n    {\n        public ActionResult Index()\n        {\n            return View(Models.UserDB.GetUsers());\n        }\n        public ActionResult userid(int id)\n        {\n            return View(Models.UserDB.GetUser(id));\n        }\n    }\n}\n</code></pre>\n\n<p>Here\'s the Index.asp view, it uses an ActionLink to create links in the correct format:  </p>\n\n<pre><code>&lt;%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Index" %&gt;\n&lt;%@ Import Namespace="MvcApplication1.Controllers" %&gt;\n&lt;%@ Import Namespace="MvcApplication1.Models" %&gt;\n\n&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;\n\n&lt;html xmlns="http://www.w3.org/1999/xhtml" &gt;\n&lt;head runat="server"&gt;\n    &lt;title&gt;&lt;/title&gt;\n&lt;/head&gt;\n&lt;body&gt;\n    &lt;div&gt;\n    &lt;h2&gt;Index of Users&lt;/h2&gt;\n           &lt;ul&gt;\n            &lt;% foreach (User user in (IEnumerable)ViewData.Model) { %&gt;\n                 &lt;li&gt;\n                       &lt;%= Html.ActionLink(user.name, "userid", new {id = user.id })%&gt;\n                 &lt;/li&gt;\n            &lt;% } %&gt;\n           &lt;/ul&gt;\n    &lt;/div&gt;\n&lt;/body&gt;\n&lt;/html&gt;\n</code></pre>\n\n<p>And here\'s the userid.aspx view which displays an individual\'s details:  </p>\n\n<pre><code>&lt;%@ Page Language="C#" AutoEventWireup="true" CodeBehind="userid.aspx.cs" Inherits="MvcApplication1.Views.Users.userid" %&gt;\n&lt;%@ Import Namespace="MvcApplication1.Controllers" %&gt;\n&lt;%@ Import Namespace="MvcApplication1.Models" %&gt;\n\n&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;\n&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;\n&lt;head runat="server"&gt;\n    &lt;title&gt;&lt;/title&gt;\n&lt;/head&gt;\n&lt;body&gt;\n    &lt;div&gt;\n        &lt;table border ="1"&gt;\n            &lt;tr&gt;\n                &lt;td&gt;\n                ID\n                &lt;/td&gt;\n                &lt;td&gt;\n                &lt;%=((User)ViewData.Model).id %&gt;\n                &lt;/td&gt;\n            &lt;/tr&gt;\n            &lt;tr&gt;\n                &lt;td&gt;\n                Name\n                &lt;/td&gt;\n                &lt;td&gt;\n                &lt;%=((User)ViewData.Model).name %&gt;\n                &lt;/td&gt;\n            &lt;/tr&gt;\n        &lt;/table&gt;\n    &lt;/div&gt;\n&lt;/body&gt;\n&lt;/html&gt;\n</code></pre>\n\n<p>And finally for completeness, here\'s the model code:  </p>\n\n<pre><code>using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Web;\n\nnamespace MvcApplication1.Models\n{\n    public class UserDB\n    {\n        private static List&lt;User&gt; users = new List&lt;User&gt;{\n            new User(){id=12345, name="Bill"},\n            new User(){id=12346, name="Claire"},\n            new User(){id=12347, name="David"}\n        };\n\n        public static List&lt;User&gt; GetUsers()\n        {\n            return users;\n        }\n\n        public static User GetUser(int id)\n        {\n            return users.First(user =&gt; user.id == id);\n        }\n\n    }\n\n    public class User\n    {\n        public int id { get; set; }\n        public string name { get; set; }\n    }\n}\n</code></pre>\n'}, {'answer_id': 834265, 'author': 'Ev.', 'author_id': 93733, 'author_profile': 'https://Stackoverflow.com/users/93733', 'pm_score': 1, 'selected': False, 'text': '<p>I\'ve been using a URL rewriter by Intelligencia:</p>\n\n<p><a href="http://urlrewriter.net/" rel="nofollow noreferrer">http://urlrewriter.net/</a></p>\n\n<p>It was so easy to configure - maybe an hour to get it all up and running. Very few problems with it... </p>\n\n<p>I\'d recommend it, but I should mentioned I\'ve not tried any other ones.</p>\n\n<p>Good luck!</p>\n'}, {'answer_id': 18045136, 'author': 'Ata S.', 'author_id': 1216609, 'author_profile': 'https://Stackoverflow.com/users/1216609', 'pm_score': 0, 'selected': False, 'text': '<p>I\'ve developed an open source <strong>NuGet library</strong> for this problem which implicitly converts EveryMvc/Url to every-mvc/url. </p>\n\n<p>Dashed urls are much more SEO friendly and easier to read. Lowercase URLs tend to create less problems. (<a href="http://www.ata.io/lowercase-dashed-route/" rel="nofollow">More on my blog post</a>)</p>\n\n<p>NuGet Package: <a href="https://www.nuget.org/packages/LowercaseDashedRoute/" rel="nofollow">https://www.nuget.org/packages/LowercaseDashedRoute/</a></p>\n\n<p>To install it, simply open the NuGet window in the Visual Studio by right clicking the Project and selecting NuGet Package Manager, and on the "Online" tab type "Lowercase Dashed Route", and it should pop up.</p>\n\n<p>Alternatively, you can run this code <strong>in the Package Manager Console:</strong></p>\n\n<p><code>Install-Package LowercaseDashedRoute</code></p>\n\n<p>After that you should open App_Start/RouteConfig.cs and comment out existing route.MapRoute(...) call and add this instead:</p>\n\n<pre><code>routes.Add(new LowercaseDashedRoute("{controller}/{action}/{id}",\n  new RouteValueDictionary(\n    new { controller = "Home", action = "Index", id = UrlParameter.Optional }),\n    new DashedRouteHandler()\n  )\n);\n</code></pre>\n\n<p>That\'s it. All the urls are lowercase, dashed, and converted implicitly without you doing anything more.</p>\n\n<p>Open Source Project Url: <a href="https://github.com/AtaS/lowercase-dashed-route" rel="nofollow">https://github.com/AtaS/lowercase-dashed-route</a></p>\n'}]
['https://Stackoverflow.com/questions/45340', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/4491/']