亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

用路由 Route 優化頁面地址

系統 2151 0

用路由 Route 優化頁面地址

剛看到某人發的關于 Route 的文章,就把我今天下午發到團隊的一封郵件轉發過吧。

全文如下,有修改:

優化地址無非就兩個選擇?URLRewrite?和?MVC?里的路由(Route)

關于?URLRewrtie?和?Route?的區別,可參考:

http://www.infoq.com/cn/news/2008/11/urlrewriting

從?.NET 3.5 SP1?起,?微軟把?MVC?路由單獨抽出來,放到?System.Web.Routing?下, WebForm?程序從此可以用上路由了.

.NET 4?對路由做了改進,?使用起來很簡單..?我們的項目都是?.NET 4?的, SEO?以后肯定是要做的,?所以我試著對?Hotel.Online?做了一下路由.

現在把使用過程中的注意事項說一下.

1, Route?使URL?的層次目錄改變了,?原來是?HotelInfo.aspx ,?路由后,很可能是?HotelInfo/45956/2011-06-21?這一小小的改變,卻帶來了大的影響.

A, PostBack :?原來的?Form action = “HotelInfo.aspx” ,?路由后變成?action=”2011-06-21”?了, PostBack?當然是不對的.?要避免這個問題,請在代碼里加上這句:

this.Form.Action?=?Page.ResolveUrl("~/HotelInfo.aspx");

B, script?標簽的問題?:?在頁面里?link?標簽的地址(href)會自動轉換,?但是?script?標簽的地址(src)卻不會自動轉換,?解決這個問題,有兩個辦法

l??A, base , <base href=”/xxx” />?如?<base href=”/xxx” /><script src=”main.js”></script>?就會自動指向?/xxx/main.js ,?這個需要注意先后順序,?如果?script?出現在?base?前,則沒有這個效果.

l??使用絕對地址.?為了簡化,?和?ResourceSite?的處理方式一樣,?我在?BasePage?里將?~?符號替換成了? http://xxx.xxx.xxxx/xxx ?,?所以,?只要繼承?BasePage?的頁面,?都可以直接寫?<script src=”~/main.js”></script>

C, A標簽的問題,?我看HTML代碼里有很多?<a href=”###” onclick=”…”?的寫法,?在不加?base?之前, ###?指向當前頁,?但是加了?base?后, ###?就指向?base?設定的地址了.為了避免這種情況,?應使用?href=”javascript:void()” onclick=”…”?或?href=”javascript:doSomething();return false;”?或干脆就不用?A?標簽.

2,?使用Route?后訪問地址從?HotelInfo.aspx?hid=45956&ds=2011-06-21& de=2011-06-25?變成了?HotelInfo/45956/2011-06-21/2011-06-25 ,?使用?Request.QueryString取不出?hid , ds, de?這些URL?參數了,?因為?hid, ds, de?就不是以?url?參數形式出現的.?要獲取這些值,?就要使用另外一個東西: Page.RouteData.Values[key]?了,?這個?key不區分大小寫,和?QueryString?一樣.

3,?腳本里的?POST / GET ,?原來的頁在都在同一個目錄層次,?所以直接

      var?form?=?document.createElement("FORM");
    
      form.action?=?"HotelList.aspx";
    

是沒有問題的,?能找到?HotelList.aspx?這個地址,?但是現在目錄層次改變了,?在這樣寫就會找不到地址,?就如第一點的?A?里所描述的.?要解決這個問題,?要使用?base?或絕對地址.

以上是我在對?Hotel.Online?做路由遇到的問題.

下面說說使用.

1, WebApplication?或?網站要是?.NET Framework 4 (也可以用?3.5 ,?但是具體有什么不同,我沒有去了解,?下面的示例代碼是針對?4?的)

2,?引用?System.Web.Routing?這個命名空間.

3,?在網站啟動的時候,注冊路由.?一般是放到?Global?的?Application_Start?里. .NET 4?里,允許用另外的方法: PreApplicationStartMethod 。

4,?注冊路由是通過?RouteTable.Routes. MapPageRoute?或?Add?方法. MapPageRoute?是對?Add?方法的簡化操作.

我的實現:

RouteItemBase.cs

      using?System;
    
      using?System.Collections.Generic;
    
      using?System.Linq;
    
      using?System.Text;
    
      using?System.Web.Routing;
    
    
      namespace?XXX.Frameworks.Route?{
    
      ????///?<summary>
    
      ????///?
    
      ????///?</summary>
    
      ????public?abstract?class?RouteItemBase?{
    
    
      ????????///?<summary>
    
      ????????///?路由名稱,必須唯一
    
      ????????///?</summary>
    
      ????????public?abstract?string?RouteName?{
    
      ????????????get;
    
      ????????}
    
    
      ????????///?<summary>
    
      ????????///?路由地址
    
      ????????///?</summary>
    
      ????????public?abstract?string?RouteUrl?{
    
      ????????????get;
    
      ????????}
    
    
      ????????///?<summary>
    
      ????????///?物理地址
    
      ????????///?</summary>
    
      ????????public?abstract?string?PhyicalUrl?{
    
      ????????????get;
    
      ????????}
    
    
      ????????///?<summary>
    
      ????????///?路由的默認值
    
      ????????///?</summary>
    
      ????????public?abstract?RouteValueDictionary?Default?{
    
      ????????????get;
    
      ????????}
    
    
      ????????///?<summary>
    
      ????????///?約束
    
      ????????///?</summary>
    
      ????????public?abstract?RouteValueDictionary?Constraint?{
    
      ????????????get;
    
      ????????}
    
    
      ????????///?<summary>
    
      ????????///?
    
      ????????///?</summary>
    
      ????????///?<param?name="routes"></param>
    
      ????????///?<param?name="item"></param>
    
      ????????public?static?void?Map(RouteCollection?routes,?RouteItemBase?item)?{
    
      ????????????routes.MapPageRoute(item.RouteName?,?item.RouteUrl,?item.PhyicalUrl,?false,?item.Default,?item.Constraint);
    
      ????????}
    
    
      ????????///?<summary>
    
      ????????///?
    
      ????????///?</summary>
    
      ????????///?<returns></returns>
    
      ????????public?abstract?object?Format();
    
      ????}
    
      }
    

HotelInfoRoute

      using?System;
    
      using?System.Collections.Generic;
    
      using?System.Linq;
    
      using?System.Text;
    
      using?System.Web.Routing;
    
      using?XXX.Frameworks.Const;
    
      using?XXX.Frameworks.Route;
    
    
      namespace?Hotel.Online.Route?{
    
    
      ????///?<summary>
    
      ????///?
    
      ????///?</summary>
    
      ????public?class?HotelInfoRoute?:?RouteItemBase?{
    
    
      ????????public?object?Hid?{
    
      ????????????get;
    
      ????????????set;
    
      ????????}
    
    
      ????????public?DateTime?Ds?{
    
      ????????????get;
    
      ????????????set;
    
      ????????}
    
    
      ????????public?DateTime?De?{
    
      ????????????get;
    
      ????????????set;
    
      ????????}
    
    
      ?
    
      ?
    
      ????????#region?RouteItemBase
    
      ????????public?override?string?RouteName?{
    
      ????????????get?{
    
      ????????????????return?RouteNames.HotelInfo.ToString();
    
      ????????????}
    
      ????????}
    
    
      ?
    
      ????????public?override?string?RouteUrl?{
    
      ????????????get?{
    
      ????????????????return?"HotelInfo/{hid}/{ds}/{de}";
    
      ????????????}
    
      ????????}
    
    
      ????????public?override?string?PhyicalUrl?{
    
      ????????????get?{
    
      ????????????????return?"~/HotelInfo.aspx";
    
      ????????????}
    
      ????????}
    
    
      ????????public?override?RouteValueDictionary?Default?{
    
      ????????????get?{
    
      ????????????????return?new?RouteValueDictionary(new?{
    
      ????????????????????Ds?=?DateTime.Now.AddDays(1).ToString(DateFormat.Date),
    
      ????????????????????De?=?DateTime.Now.AddDays(2).ToString(DateFormat.Date)
    
      ????????????????});
    
      ????????????}
    
      ????????}
    
    
      ????????public?override?RouteValueDictionary?Constraint?{
    
      ????????????get?{
    
      ????????????????return?new?RouteValueDictionary(new?{
    
      ????????????????????Hid?=?@"\d+",
    
      ????????????????????Ds?=?@"\d{4}-\d{2}-\d{2}",
    
      ????????????????????De?=?@"\d{4}-\d{2}-\d{2}"
    
      ????????????????});
    
      ????????????}
    
      ????????}
    
    
      ????????public?override?object?Format()?{
    
      ????????????return?new?{
    
      ????????????????Hid?=?this.Hid,
    
      ????????????????Ds?=?this.Ds.ToString(DateFormat.Date),
    
      ????????????????De?=?this.De.ToString(DateFormat.Date)
    
      ????????????};
    
      ????????}
    
      ????????#endregion
    
      ????}
    
      }
    

注意?HotelInfoRoute?的?RouteUrl ,?HotelInfo/{hid}/{ds}/{de}?Hid, ds ,de?即路由的參數,?不區分大小寫.

為了編程方便(?強類型?),?我同時在這個類里定義了?Hid, Ds , De?幾個屬性( 注意: 和路由參數完全一樣,? 不區分大小寫 ),?這幾個屬性會在頁面獲取?Route Url?和獲取路由參數里發揮作用,會面會說.

Global?里

      ????????void?Map(RouteCollection?routes)?{
    
      ????????????routes.RouteExistingFiles?=?true;
    
      ????????????routes.Ignore("{resource}.axd/{*pathInfo}");
    
      ????????????routes.Ignore("{*AllRes}",?new?{
    
      ????????????????AllRes?=?@".*?\.(?!aspx)(.*)"
    
      ????????????});
    
      ????????????
    
      ????????????//RouteItemBase.Map(routes,?new?HotelInfoRoute());
    
      ????????????RouteHelper.AutoLoadRoutes(routes,?typeof(HotelInfoRoute).Assembly);
    
      ????????}
    
    
      ????????void?Application_Start(object?sender,?EventArgs?e)?{
    
      ????????????Map(RouteTable.Routes);
    

….

….

RouteHelper.AutoLoadRoutes?是用來自動發現某個?Assembly?下所有繼承自?RouteItemBase?的類,?并自動注冊到當前的路由表中,?這樣,就不用每加個路由,都要手動修改?Global了.

頁面里

      var?routeData?=?this.Page.RouteData.Values;
    
      var HotelID?=?(routeData["hid"]????"").ToString().ToInt(-110),
    

這樣寫,有些隱患,?假如路由參數?{hid}?變成了?{hotelID}?了,?而你在頁面里還在傻傻的用?hid ,?當然是取不到值的,?怎么辦呢??用強類型可以很好的避免這個問題.?怎么用?

      Page.RouteData.Values 是一個 RouteValueDictionary 類型, 繼承自 IDictionary<string,?object> , 我針對 IDctionary<string, object> 做了一個擴展方法.
    
      ?
    
      ????????public?static?T?ToEntity<T>(this?IDictionary<string,?object>?dict)?where?T?:?new()?{
    
      ????????????var?t?=?typeof(T);
    
      ????????????var?ps?=?t.GetProperties();
    
      ????????????T?tmp?=?new?T();
    
    
      ????????????foreach?(var?p?in?ps)?{
    
      ????????????????if?(!p.CanWrite)
    
      ????????????????????continue;
    
      ????????????????//var?v?=?dict.Get(p.Name);
    
      ????????????????if?(dict.ContainsKey(p.Name))?{
    
      ????????????????????p.SetValue(tmp,?Convert.ChangeType(dict[p.Name],?p.PropertyType),?null);
    
      ????????????????}
    
      ????????????}
    
      ????????????return?tmp;
    
      ????????}
    
      ?
    

然后直接用:

      this.RouteData?=?this.Page.RouteData.Values.ToEntity<HotelInfoRoute>(); 就把該頁面的路由參數提取出來了
    
      var HotelID 直接等于 RouteData.Hid 就是了.
    
      ?
    
      獲取路由后的地址, 被我簡化成如下了, 
    
      ????????public?static?string?GetRoutedUrl<T>(T?routeData)
    
      ????????????where?T?:?RouteItemBase?{
    
      ????????????return?RouteTable.Routes.GetVirtualPath(HttpContextHelper.Current.Request.RequestContext,?routeData.RouteName.ToString(),?new?RouteValueDictionary(
    
      ????????????????routeData.Format()
    
      ????????????????)).VirtualPath;
    
      ????????}
    
      ?
    
      HttpContextHelper 的定義在 XXX.Frameworks.Extends.HttpContextHelper 中定義, 為什么不用 HttpContext? 因為單元測試的時候會有問題.
    
      ????????????return?RouteHelper.GetRoutedUrl<HotelInfoRoute>(new?HotelInfoRoute()?{
    
      ????????????????Hid?=?hotelID.ToString(),
    
      ????????????????Ds?=?this.BeginDate,
    
      ????????????????De?=?this.EndDate
    
      ????????????});
    
      ?
    
      還是強類型, 不怕改.
    
      ?
    
      ?
    
      ?
    
      ?
    
      將以有地址重定向到新地址
    
      HotelInfo.aspx 這個地址肯定以經被搜索引擎收錄, 現在如果棄用這樣的地址, 對SEO和以有用戶來說, 是最不希望出現的.
    
      如果把老地址301 到新地址,對SEO和用戶不會有任何影響. 為了達到這個效果,我加了一個方法:
    
      ?
    
      ????????public?static?void?RedirectToRouted(this?Page?page,?string?routeName)?{
    
      ????????????if?(page.RouteData.Route?==?null)?{
    
      ????????????????var?context?=?HttpContextHelper.Current;
    
      ????????????????var?querys?=?context.Request.QueryString;
    
      ????????????????var?keys?=?querys.Cast<string>().ToList();
    
    
      ????????????????RouteValueDictionary?datas?=?new?RouteValueDictionary();
    
      ????????????????keys.ForEach((k)?=>?{
    
      ????????????????????datas.Add(k,?querys[k]);
    
      ????????????????});
    
    
      ????????????????var?vp?=?RouteTable.Routes.GetVirtualPath(context.Request.RequestContext,?routeName,?new?RouteValueDictionary(datas));
    
      ????????????????context.Response.Status?=?"301?Moved?Permanently";
    
      ????????????????context.Response.RedirectLocation?=?vp.VirtualPath;
    
      ????????????????context.Response.End();
    
      ????????????}
    
      ????????}
    
      ?
    
      在需要將老地址轉成新地址的頁面里,加上:
    
      ????????protected?override?void?OnPreInit(EventArgs?e)?{
    
      ????????????this.Page.RedirectToRouted(?RouteNames.HotelInfo.ToString()?);
    
    
      ????????????base.OnPreInit(e);
    
      ????????}
    
分類: C#

用路由 Route 優化頁面地址


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美毛片免费 | 精品无人区乱码一区二区三区手机 | 久久免费观看爱情动作片 | 国产在视频线精品视频2021 | 日韩欧美一区二区三区在线 | 久草在线影视 | 青青草久热精品视频在线观看 | 可以看美女隐私的网站 | 日韩精品a| 97精品国产 | 在线黄色.com | 99久久精品免费看国产四区 | 日韩毛片高清在线看 | 亚洲免费色视频 | 久久精品成人欧美大片免费 | 国产福利在线永久视频 | 午夜激情网站 | 天天操妹子 | 国产精品免费_区二区三区观看 | 中文字幕在线综合 | 色综合久久天天综合绕观看 | 四虎永久在线免费观看 | 久久综合久久综合久久综合 | 曰本三级男人吃奶水 | 两性视频网站 | 国产在线一区二区三区欧美 | 毛片毛片毛片毛片 | 午夜毛毛片 | 一级成人毛片免费观看欧美 | 国产色在线 | 亚洲日产综合欧美一区二区 | 男人的天堂久久精品激情 | 日本一级欧美一级中文 | 91国自产精品中文字幕亚洲 | 手机看片日韩日韩韩 | 999精品视频在线观看 | 成人国产精品一区二区网站 | 99久久99久久精品免费看子 | 男人都懂的网址 | 福利视频国产 | 中文字幕欧美日韩久久 |