ASP.NET的友好URL
Python框架始终提供处理URL的方法,这些URL以优雅的方式传达请求的数据,例如http://somewhere.overtherainbow.com/userid/123424/
我希望我们注意到结束路径/ userid / 123424 /
我们如何在ASP.NET中做到这一点?
解决方案
回答
另外,请签出ASP.NET MVC或者在Webforms上进行设置(ASP.NET 3.5 SP1中新的System.Web.Routing命名空间)
回答
本示例使用ASP.NET路由来实现友好的URL。
应用程序处理的映射示例如下:
http:// samplesite / userid / 1234 http://samplesite/users.aspx?userid = 1234
http:// samplesite / userid / 1235 http://samplesite/users.aspx?userid = 1235
本示例使用查询字符串,并且避免了修改aspx页面上的代码的任何要求。
<system.web> <compilation debug="true"> <assemblies> … <add assembly="System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> </assemblies> </compilation> … <httpModules> … <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> </httpModules> </system.web> <system.webServer> … <modules> … <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> </modules> <handlers … <add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/> </handlers> </system.webServer>
定义从友好URL到aspx页面的映射,保存请求的用户ID供以后使用。
void Application_Start(object sender, EventArgs e) { RegisterRoutes(RouteTable.Routes); } public static void RegisterRoutes(RouteCollection routes) { routes.Add("UseridRoute", new Route ( "userid/{userid}", new CustomRouteHandler("~/users.aspx") )); }
在进行路由之前,将querystring添加到当前上下文。
using System.Web.Compilation; using System.Web.UI; using System.Web; using System.Web.Routing; public class CustomRouteHandler : IRouteHandler { public CustomRouteHandler(string virtualPath) { this.VirtualPath = virtualPath; } public string VirtualPath { get; private set; } public IHttpHandler GetHttpHandler(RequestContext requestContext) { // Add the querystring to the URL in the current context string queryString = "?userid=" + requestContext.RouteData.Values["userid"]; HttpContext.Current.RewritePath( string.Concat( VirtualPath, queryString)); var page = BuildManager.CreateInstanceFromVirtualPath (VirtualPath, typeof(Page)) as IHttpHandler; return page; } }
aspx页面上的代码可供参考。
protected void Page_Load(object sender, EventArgs e) { string id = Page.Request.QueryString["userid"]; switch (id) { case "1234": lblUserId.Text = id; lblUserName.Text = "Bill"; break; case "1235": lblUserId.Text = id; lblUserName.Text = "Claire"; break; case "1236": lblUserId.Text = id; lblUserName.Text = "David"; break; default: lblUserId.Text = "0000"; lblUserName.Text = "Unknown"; break; }
回答
这是一个替代示例,该示例也使用ASP.NET路由来实现友好的URL。
应用程序处理的映射示例如下:
http:// samplesite / userid / 1234 http://samplesite/users.aspx?userid = 1234
http:// samplesite / userid / 1235 http://samplesite/users.aspx?userid = 1235
此示例不使用查询字符串,但是需要在aspx页面上添加其他代码。
<system.web> <compilation debug="true"> <assemblies> … <add assembly="System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> </assemblies> </compilation> … <httpModules> … <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> </httpModules> </system.web> <system.webServer> … <modules> … <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> </modules> <handlers … <add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/> </handlers> </system.webServer>
定义从友好URL到aspx页面的映射,保存请求的用户ID供以后使用。
void Application_Start(object sender, EventArgs e) { RegisterRoutes(RouteTable.Routes); } public static void RegisterRoutes(RouteCollection routes) { routes.Add("UseridRoute", new Route ( "userid/{userid}", new CustomRouteHandler("~/users.aspx") )); }
将包含参数的路由上下文传递到页面。 (请注意IRoutablePage的定义)
using System.Web.Compilation; using System.Web.UI; using System.Web; using System.Web.Routing; public interface IRoutablePage { RequestContext RequestContext { set; } } public class CustomRouteHandler : IRouteHandler { public CustomRouteHandler(string virtualPath) { this.VirtualPath = virtualPath; } public string VirtualPath { get; private set; } public IHttpHandler GetHttpHandler(RequestContext requestContext) { var page = BuildManager.CreateInstanceFromVirtualPath (VirtualPath, typeof(Page)) as IHttpHandler; if (page != null) { var routablePage = page as IRoutablePage; if (routablePage != null) routablePage.RequestContext = requestContext; } return page; } }
请注意IRoutablePage的实现。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.Routing; public partial class users : System.Web.UI.Page, IRoutablePage { protected RequestContext requestContext; protected object RouteValue(string key) { return requestContext.RouteData.Values[key]; } protected void Page_Load(object sender, EventArgs e) { string id = RouteValue("userid").ToString(); switch (id) { case "1234": lblUserId.Text = id; lblUserName.Text = "Bill"; break; case "1235": lblUserId.Text = id; lblUserName.Text = "Claire"; break; case "1236": lblUserId.Text = id; lblUserName.Text = "David"; break; default: lblUserId.Text = "0000"; lblUserName.Text = "Unknown"; break; } } #region IRoutablePage Members public RequestContext RequestContext { set { requestContext = value; } } #endregion }
回答
这是使用ASP.NET MVC的另一种方法
首先,这是带有两个动作的控制器代码。索引从模型中获取用户列表,用户标识获取单个用户:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Mvc.Ajax; namespace MvcApplication1.Controllers { public class UsersController : Controller { public ActionResult Index() { return View(Models.UserDB.GetUsers()); } public ActionResult userid(int id) { return View(Models.UserDB.GetUser(id)); } } }
这是Index.asp视图,它使用ActionLink创建正确格式的链接:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Index" %> <%@ Import Namespace="MvcApplication1.Controllers" %> <%@ Import Namespace="MvcApplication1.Models" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title></title> </head> <body> <div> <h2>Index of Users</h2> <ul> <% foreach (User user in (IEnumerable)ViewData.Model) { %> <li> <%= Html.ActionLink(user.name, "userid", new {id = user.id })%> </li> <% } %> </ul> </div> </body> </html>
这是显示个人详细信息的userid.aspx视图:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="userid.aspx.cs" Inherits="MvcApplication1.Views.Users.userid" %> <%@ Import Namespace="MvcApplication1.Controllers" %> <%@ Import Namespace="MvcApplication1.Models" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <div> <table border ="1"> <tr> <td> ID </td> <td> <%=((User)ViewData.Model).id %> </td> </tr> <tr> <td> Name </td> <td> <%=((User)ViewData.Model).name %> </td> </tr> </table> </div> </body> </html>
最后为了完整起见,下面是模型代码:
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace MvcApplication1.Models { public class UserDB { private static List<User> users = new List<User>{ new User(){id=12345, name="Bill"}, new User(){id=12346, name="Claire"}, new User(){id=12347, name="David"} }; public static List<User> GetUsers() { return users; } public static User GetUser(int id) { return users.First(user => user.id == id); } } public class User { public int id { get; set; } public string name { get; set; } } }
回答
我一直在使用Intelligencia的URL重写器:
http://urlrewriter.net/
配置它大概一个小时就可以使它全部启动并运行非常容易。很少有问题...
我会推荐它,但是我应该提到我没有尝试过其他任何方法。
祝你好运!