ASP.NET 的友好 URL

ASP.NET 的友好 URL

Friendly URLs for ASP.NET

Python 框架总是提供处理 URL 的方法,这些 URL 以优雅的方式传达请求的数据,例如 http://somewhere.overtherainbow.com/userid/123424/

我想让你注意结束路径 /userid/123424/

在 ASP.NET 中如何做到这一点?


此示例使用 ASP.NET 路由来实现友好的 URL。

应用程序处理的映射示例如下:

http://samplesite/userid/1234 - http://samplesite/users.aspx?userid=1234
http://samplesite/userid/1235 - http://samplesite/users.aspx?userid=1235

本示例使用查询字符串,并避免任何需要修改 aspx 页面上的代码。

第 1 步 - 将必要的条目添加到 web.config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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

第 2 步 - 在 global.asax 中添加路由表

定义从友好 URL 到 aspx 页面的映射,保存请求的用户 ID 供以后使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
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")
    ));
}

第 3 步 - 实现路由处理程序

在路由发生之前将查询字符串添加到当前上下文。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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;
    }
}

来自 users.aspx 的代码

aspx页面上的代码供参考。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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 页面上附加代码。

第 1 步 - 将必要的条目添加到 web.config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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

第 2 步 - 在 global.asax 中添加路由表

定义从友好 URL 到 aspx 页面的映射,保存请求的用户 ID 供以后使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
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")
    ));
}

第 3 步 - 实现路由处理程序

将包含参数的路由上下文传递给页面。 (注意IRoutablePage的定义)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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;
    }
}

第 4 步 - 检索目标页面上的参数

注意IRoutablePage 的实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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
}

我一直在使用 Intelligencia 的 URL 重写器:

http://urlrewriter.net/

配置非常简单 - 可能需要一个小时才能全部启动并运行。很少有问题...

我会推荐它,但我应该提到我没有尝试过任何其他的。

祝你好运!


这是使用 ASP.NET MVC 的另一种方法

首先,这是包含两个操作的控制器代码。 Index 从模型中获取用户列表,userid 获取单个用户:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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 以正确的格式创建链接:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
%@ 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
    h2Index 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 视图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
%@ 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

最后为了完整起见,下面是模型代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MvcApplication1.Models
{
    public class UserDB
    {
        private static ListUser users = new ListUser{
            new User(){id=12345, name="Bill"},
            new User(){id=12346, name="Claire"},
            new User(){id=12347, name="David"}
        };

        public static ListUser 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; }
    }
}

我为这个问题开发了一个开源 NuGet 库,它隐式地将 EveryMvc/Url 转换为 every-mvc/url。

虚线网址对 SEO 更友好且更易于阅读。小写 URL 往往会产生较少的问题。 (更多关于我的博文)

NuGet 包:https://www.nuget.org/packages/LowercaseDashedRoute/

要安装它,只需在 Visual Studio 中打开 NuGet 窗口,方法是右键单击项目并选择 NuGet 包管理器,然后在"在线"选项卡上键入"小写虚线路径",它应该会弹出。

或者,您可以在包管理器控制台中运行此代码:

Install-Package LowercaseDashedRoute

之后,您应该打开 App_Start/RouteConfig.cs 并注释掉现有的 route.MapRoute(...) 调用并添加它:

1
2
3
4
5
6
routes.Add(new LowercaseDashedRoute("{controller}/{action}/{id}",
  new RouteValueDictionary(
    new { controller ="Home", action ="Index", id = UrlParameter.Optional }),
    new DashedRouteHandler()
  )
);

就是这样。所有的 url 都是小写、虚线和隐式转换,无需您执行任何操作。

开源项目网址:https://github.com/AtaS/lowercase-dashed-route


另外,请查看 ASP.NET MVC,或者如果您设置在 webforms 上,请查看 ASP.NET 3.5 SP1 中的新 System.Web.Routing 命名空间


推荐阅读

    linux常用的命令路径?

    linux常用的命令路径?,地址,工作,基础,网络,管理,系统,信息,命令,企业,服务,l

    linux数据库同步命令?

    linux数据库同步命令?,信息,系统,汽车,车辆,服务,工作,通信,一致,分析,数据,D

    linux改变命令的路径?

    linux改变命令的路径?,数字,第一,目录,工作,一致,名称,系统,命令,文件夹,代

    linux中显示路径命令?

    linux中显示路径命令?,系统,地址,工作,信息,时间,命令,数据,网络,路径,名字,l

    linux建立数据库命令?

    linux建立数据库命令?,软件,系统,工作,数据,密码,工具,数据库,一致,网络,服

    linux保存路径命令行?

    linux保存路径命令行?,状态,地址,电脑,档案,系统,底部,软件,密码,命令,文件,l

    linux命令进数据库?

    linux命令进数据库?,地址,系统,名字,服务,密码,命令,读法,数据库,操作系统,

    linux相对路径命令?

    linux相对路径命令?,工作,名字,路径,目录,管理,信息,系统,位置,名称,基础,lin

    linux清空表数据命令?

    linux清空表数据命令?,系统,数据,软件,名称,不了,命令,文件,电脑,地址,位置,L

    linux多路径查看命令?

    linux多路径查看命令?,设备,软件,网络,工具,系统,情况,下降,公司,名称,大幅,

    linux拷贝数据命令?

    linux拷贝数据命令?,系统,地址,文件,数据,命令,目录,服务,基本知识,项目,密

    linux路径命令解释?

    linux路径命令解释?,系统,信息,设备,数据,工具,命令,文件,标准,发行,时间,lin

    linux相对路径和命令?

    linux相对路径和命令?,地址,工作,信息,数据,系统,命令,文件,目录,时间,路径,l

    linux显示路径命令?

    linux显示路径命令?,系统,信息,工作,数据,名称,位置,标准,环境,时间,命令,lin

    linux拷贝路径命令行?

    linux拷贝路径命令行?,系统,文件,命令,目录,名称,源文件,文件夹,目标,路径,

    linux数据库检查命令?

    linux数据库检查命令?,服务,状态,地址,位置,系统,信息,命令,工作,情况,密码,

    linux路径截取命令?

    linux路径截取命令?,标准,图片,命令,环境,工具,信息,软件,系统,文件,目录,Lin

    linux命令进去数据库?

    linux命令进去数据库?,地址,服务,名字,系统,数据库,工具,基础,工作,管理,网

    linux数据库基础命令?

    linux数据库基础命令?,地址,工作,基础,系统,命令,信息,情况,工具,设备,目录,l

    linux挂载命令路径?

    linux挂载命令路径?,服务,信息,系统,电脑,情况,工具,网络,命令,磁盘,目录,Lin