ASP.NET 4.0使用Routing优化URL实例教程

ASP.NET4.0中我们使用Routing可以很轻松的将http://localhost/Customer.aspx?Id=1优化成http://localhost/Custome/1的形式,下面来看具体实例。

首先,建立一个空的ASP.NET 4.0 Web form项目,建立Global.asax文件,在Glolal类里,我们添加如下代码:

namespace EasyURL
{
    public class Global : System.Web.HttpApplication
    {
        protected void Application_Start(object sender, EventArgs e)
        {
            RegisterRoutes(RouteTable.Routes);
        }
        public static void RegisterRoutes(RouteCollection routeCollection)
        {
            //routeCollection.MapPageRoute("RouteForCustomer", "Customer/{Id}", "~/Customer.aspx")
            // 可以使用上面的,但是最好使用下面的,这样可以限制Id为数字
            routeCollection.MapPageRoute("RouteForCustomer", "Customer/{Id}", "~/Customer.aspx", true, null, new RouteValueDictionary(new { Id = "\\d+" }));
        }
    }
}

然后添加一个Customer.aspx文件,代码非常简单,如下:

public partial class Customer : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string id = Page.RouteData.Values["Id"].ToString();
        Response.Write("<h1>Customer详细页</h1>");
        Response.Write(string.Format("CustomerID : {0}", id));
    }
}

注意我们是用Page.RouteData.Values["Id"]来取的值。

这样,当我们在访问http://localhost/customer/1的时候,就显示了我们预想的页面:
Customer详细页

CustomerID : 1

延伸一

其实上面的效果已经很简单的实现了,但是我们发现我们必须要用Page.RouteData.Values["Id"]这种形式来取值,而不是我们平时所用的Page.QueryString["Id"]来取,那我们能否做到这一点呢?

我们知道,在PageLoad之前Request的值都有初始化好的,所以如果我们要使用这种方式的时候,必须在这个周期之前将RouteData.Values的值都加到QueryString里,好,我们来试试,先建立一个PageBase基类(后面所有的页面都要继承此类),代码如下:

public abstract class PageBase : System.Web.UI.Page
{
    protected override void OnInitComplete(EventArgs e)
    {
        base.OnInitComplete(e);
        Page.RouteData.Values.Keys.ToList().ForEach(key =>
        {
            Request.QueryString.Add(key, Page.RouteData.Values[key].ToString());
        });
    }
}

运行之后,我们发现出了黄页:

Exception Details: System.NotSupportedException: Collection is read-only.

Source Error:

Line 20:             Page.RouteData.Values.Keys.ToList().ForEach(key =>
Line 21:             {
Line 22:                 Request.QueryString.Add(key, Page.RouteData.Values[key].ToString());
Line 23:             });
Line 24:         }

原来是QueryString这个集合是只读的,通过老赵的文章一个较完整的关键字过滤解决方案我们来改写一下代码:

public static class GlobalValues
{
    public static PropertyInfo NameObjectCollectionBaseIsReadOnly;
    static GlobalValues()
    {
        Type type = typeof(NameObjectCollectionBase);
        NameObjectCollectionBaseIsReadOnly = type.GetProperty(
            "IsReadOnly",
            BindingFlags.Instance | BindingFlags.NonPublic);
    }
}
public abstract class PageBase : System.Web.UI.Page
{
    protected override void OnInitComplete(EventArgs e)
    {
        base.OnInitComplete(e);
        // 将集合改成可写的
        GlobalValues.NameObjectCollectionBaseIsReadOnly.SetValue(Request.QueryString, false, null);
        Page.RouteData.Values.Keys.ToList().ForEach(key =>
        {
            // 添加RouteData.Values的name/value对添加到QueryString集合里
            Request.QueryString.Add(key, Page.RouteData.Values[key].ToString());
        });
    }
}

然后使用我们平时用的代码:

protected void Page_Load(object sender, EventArgs e)
{
    //string id = Page.RouteData.Values["Id"].ToString();
    string id = Request.QueryString["Id"];
    Response.Write("<h1>Customer详细页</h1>");
    Response.Write(string.Format("CustomerID : {0}", id));
}

运行一下,完美,啊哈!OK,在aspx里添加一个form表单,点击一个button几次试试,完蛋了,浏览器地址栏的地址变成了:

http://localhost/Customer/1?Id=1&Id=1&Id=1

原来是,由于我们每次都往QueryString里添加Id这个key,结果每次回发的时候就附加到URL上了,得想办法在页面结束以后从QueryString里删除这个key,由于在OnUnload周期Request/Response已经被清空了,所以我们要在之前的周期内处理,代码如下:

protected override void OnPreRenderComplete(EventArgs e)
{
    Page.RouteData.Values.Keys.ToList().ForEach(key =>
    {
        Request.QueryString.Remove(key);
    });
    base.OnPreRenderComplete(e);
}

照例运行,OK,完美,再试几下其它的case,也没什么问题。

注:由于好久不用web form做项目了,所以不太确信上述代码用的OnInitComplete/OnPreRenderComplete周期是否是合理的周期,目前运行起来是没有问题的,有时间再详细研究一下。

延伸二

延伸一的代码,颇为复杂,而且也不知道有没有副作用,其实实际项目中,一般我们都封装自己的GetParameter方法,所以其实我们可以这样用,相对就简单多了:

namespace EasyURL
{
    public abstract class PageBase : System.Web.UI.Page
    {
        public string GetQueryString(string key, string defaultValue = "")
        {
            if (Page.RouteData.Values.Keys.Contains(key))
                return Page.RouteData.Values[key].ToString();
            else if (string.IsNullOrWhiteSpace(Request.QueryString[key]))
                return Request.QueryString[key];
            else
                return defaultValue;
        }
    }
    public partial class Customer : PageBase
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string id = this.GetQueryString("id");
            Response.Write("<h1>Customer详细页</h1>");
            Response.Write(string.Format("CustomerID : {0}", id));
        }
    }
}

运行,没问题,而且也不存在在URL上再次附加?Id=1的问题了。

Asp.Net 4.0 SEO增强之 UrlRouting

1. Url Routing 的通常用法
UrlRouting在Asp.Net Mvc项目中被广泛使用,在Mvc中很好用,所以移植到了webform中,我们先看下在webform中的使用方式
假定一个使用场景:我们需要做博客每日文章的页面,我们希望的url地址是:
/archive/2010/05/10/default.aspx
这个地址将被映射到~/posts.aspx文件上

要使用UrlRouting,需要将UrlRouting的规则注册到RouteTable中,如下Global文件中注册Routing规则的代码

public static void RegisterRoutes(RouteCollection routes)
{
    routes.Ignore("{resource}.axd/{*pathInfo}");
 
    routes.MapPageRoute("blogs", //给这个UrlRouting规则起一个名字
        "archive/{year}/{month}/{date}/default.aspx", //希望的友好Url地址格式
        "~/blogs.aspx", //映射到的aspx页面路径
        false, //是否需要检查用户权限
        new RouteValueDictionary{ { "year", DateTime.Now.Year },
            { "month", DateTime.Now.Month },
            {"date", DateTime.Now.Date}
        },//参数的默认值
        new RouteValueDictionary { 
            {"year",@"(19|20)\d{2}"},
            {"month",@"\d{1,2}"},
            {"date",@"\d{1,2}"}
        } //参数的规则,我们在这里限制url中的年月日是我们想要的数据格式
        );
 
}
 
void Application_Start(object sender, EventArgs e)
{
    //在Application_Start时注册的Routing规则
    RegisterRoutes(RouteTable.Routes);
}

2. 在页面中使用UrlRouting参数值

  1) 在后台代码中使用Route的值

protected void Page_Load(object sender, EventArgs e)
{
    string year = (string)RouteData.Values["year"];
    string month = (string)RouteData.Values["month"];
    string date = (string)RouteData.Values["date"];
}

  2) 在页面上使用

<asp:Literal ID="literalYear" runat="server" Text="<%$RouteValue:year %>"></asp:Literal>
    -<asp:Literal ID="literal1" runat="server" Text="<%$RouteValue:month %>"></asp:Literal>
    -<asp:Literal ID="literal2" runat="server" Text="<%$RouteValue:date %>"></asp:Literal>

  3) 在DataSource中使用RouteParameter

<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:TestDb %>"
    SelectCommand="SELECT BlogID,BlogTitle FROM Blogs Where Category = @category">
    <SelectParameters>
        <asp:RouteParameter Name="category" RouteKey="category" />
    </SelectParameters>
</asp:SqlDataSource>

  4) 在页面上显示RouteUrl

<a href='<%=GetRouteUrl("blogs",new {year=2010,month=05,date=05}) %>'>2010年5月1日的博客</a>

3. UrlRouting和UrlRewrite的区别

UrlRouting相对于Url重写是一个比较新的事物,UrlRouting的长处是可以做双向转换,既可以做url重写,还可以根据一些参数获得重写后的Url地址,但是它也有自己的不足之处,比如说如果你想连域名一起重写,比如博客地址yukaizhao.cnblogs.com这样的重写,UrlRouting就做不到了,只能用UrlRewrite。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索string
, class
, static
, 代码
aspx
,以便于您获取更多的相关知识。

时间: 2025-01-20 19:50:36

ASP.NET 4.0使用Routing优化URL实例教程的相关文章

asp For Each Next 用法与For Each实例教程

在For Each ... Next循环类似,对于... Next循环.而不是重复陈述的指定的次数, 每名... Next循环重复的对象集合为数组中的每个元素的声明(或每个项目). 下面的代码片断创建下拉列表中选择其中一个数组元素: Select ActionSelect AllTry It<% Dim bookTypes(7) 'creates first array bookTypes(0)="Classic" bookTypes(1)="Information B

asp do while 循环语法与do while实例教程

在do while循环的另一种常用后... Next循环的循环.在do while循环语句重复语句 块的次数不定.重复的陈述或者当条件为真或直到条件变为True.语法如下所示: Do [While|Until] condition   statements Loop Do    statements Loop [While|Until] condition 在这方面,这个循环内的代码将执行至少一次的情况.在有一个例子: 下面的例子定义了一个循环,开始与i = 0.循环将继续运行,因为我只要小于或

asp.net 2.0中的url映射

asp.net 介绍 url映射是asp.net 2.0的一个新的特性,它可以让开发人员把一个页映射到另一个url上.如果一个url请求过来,程序会自动把它重新映射到服务端.例如,如果你在程序中配置了把~/Beverages.aspx映射到了~/ProductsByCategory.aspx?CategoryID=1&CategoryName=Beverages,那么当用户在浏览器中输入了http://YourSite.com/Beverages.aspx,服务器会接收后会自动的转到http:/

ASP.NET 2.0不能识别eurl.axd的解决方法

在IIS6中同时启用了ASP.NET 2.0 和 ASP.NET 4.0 后,网站程序可能会出现如下错误:" System.Web.HttpException: Path '//eurl.axd/' was not found. " 错误发生的原因是当ASP.NET检测到Web站点配置为使用ASP.NET 4.0,本地ASP.NET 4.0 的组件会传递一个不能扩展的 URL到ASP.NET的管理程序作进一步处理.但是,如果一个低于ASP.NET 4.0 的网站配置为使用ASP.NET

asp 验证友代码与验证码实例教程

<head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>asp 验证友代码与验证码实例教程</title> </head> <body> <input name="" type="text" />验证码<img src=&qu

一起谈.NET技术,VS 2010 和 .NET 4.0 系列之《在ASP.NET 4 Web Forms中实现URL导向》篇

本系列文章导航 VS 2010 和 .NET 4.0 系列之<ASP.NET 4 中的SEO改进 >篇 VS 2010 和 .NET 4.0 系列之<干净的Web.Config文件 >篇 VS 2010 和 .NET 4.0 系列之<起始项目模板>篇 VS 2010 和 .NET 4.0 系列之<多定向支持>篇 VS 2010 和 .NET 4.0 系列之<多显示器支持>篇 VS 2010 和 .NET 4.0 系列之<代码优化的Web开发

艾伟_转载:VS 2010 和 .NET 4.0 系列之《在ASP.NET 4 Web Forms中实现URL导向》篇

本系列文章导航 VS 2010 和 .NET 4.0 系列之<ASP.NET 4 中的SEO改进 >篇 VS 2010 和 .NET 4.0 系列之<干净的Web.Config文件 >篇 VS 2010 和 .NET 4.0 系列之<起始项目模板>篇 VS 2010 和 .NET 4.0 系列之<多定向支持>篇 VS 2010 和 .NET 4.0 系列之<多显示器支持>篇 VS 2010 和 .NET 4.0 系列之<代码优化的Web开发

VS 2010 和 .NET 4.0 系列之《在ASP.NET 4 Web Forms中实现URL导向》篇

本系列文章导航 VS 2010 和 .NET 4.0 系列之<ASP.NET 4 中的SEO改进 >篇 VS 2010 和 .NET 4.0 系列之<干净的Web.Config文件 >篇 VS 2010 和 .NET 4.0 系列之<起始项目模板>篇 VS 2010 和 .NET 4.0 系列之<多定向支持>篇 VS 2010 和 .NET 4.0 系列之<多显示器支持>篇 VS 2010 和 .NET 4.0 系列之<代码优化的Web开发

Asp.Net MVC2.0 Url 路由入门

     本篇文章是初识Asp.Net MVC2.0 的后续的介绍.此文将从Routing未开放源代码开始,还会对Asp.Net的Url重写技术做个简单介绍.并简单介绍Asp.Net MVC2.0 Url路由技术的使用.      Url路由是MVC很重要的核心的一部分.不过它是单独于MVC项目,而且没有开源.它作为微软的一个独立的项目抽取了出来,在Asp.Net MVC中只是引用了这个dll.新建一个MVC Web项目,打开Global.asax.我们看到系统帮我们添加了using Syste