首页 / 知识

ASP.NET 的友好 URL

2023-04-14 07:11:00

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 命名空间


方法数据请求框架

最新内容

相关内容

热门文章

推荐文章

标签云

猜你喜欢