ASP.NET WebFormのルーティング

8717 ワード

暇を盗んで、ブログ園を見て、筒が書いた編があります:ASP.NETのルーティング
私は2つ前のメールをめくって、私が当時プロジェクトの余暇に研究したので、その時はまだMVCを使っていません.すべてのプロジェクトはWebFormです.
この案は実行可能だと思いますが、ある同志の一言:下層の経路マッピングに基づいているのではなく、効率が高くないのか、URLRewriteがいいです.私は笑っておしっこをした.鳥を計算すると,みな昔のことだ.今考えてみると、この同志はまだいい人で、他の人と比べると、やはり偉岸だ(私は本当にそう思っている).
 
本文
 
アドレスの最適化は、URLRewriteとMVCのルートの2つの選択にほかならない.
URLRewrtieとRouteの違いについては、以下を参照してください.
http://www.infoq.com/cn/news/2008/11/urlrewriting
 
からNET 3.5 SP 1からマイクロソフトは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)は自動的に変換されません.この問題を解決するには、2つの方法があります.
l A,base,例えば
 
C,Aタグの問題ですが、HTMLコードには以上是我在酒店。在线路上发生了问题。接下来关于使用的话.1,如果WebApplication或Web网站的话.NET Framework 4(3.5也可以使用,具体上不知道是什嚒不同,但以下的桑普尔科德是4相关)2,引用System.Web.Routing的网络3,网站起动时,会登记规则.一般的にGlobalのApplication_斯塔利NET 4,可以用其他方法使用:P e r p p a plicationStartMethod,我可以适用于Vmaster.请参照SharedMaster.Offline. VmasterInit 4,登録ルートはRouteTable.Routes. MapPageRouteまたはAddメソッド.MapPageRoute是Add方法的简略化操作.私の実现:RouteItemBase.cs   1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Web.Routing; 6 7 namespace XXX.Frameworks.Route { 8 /// <summary> 9 /// 10 /// </summary> 11 public abstract class RouteItemBase { 12 13 /// <summary> 14////ルーティング名、一意でなければなりません 15 /// </summary> 16 public abstract string RouteName { 17 get; 18 } 19 20 /// <summary> 21////ルーティングアドレス 22 /// </summary> 23 public abstract string RouteUrl { 24 get; 25 } 26 27 /// <summary> 28////物理アドレス 29 /// </summary> 30 public abstract string PhyicalUrl { 31 get; 32 } 33 34 /// <summary> 35////ルーティングのデフォルト値 36 /// </summary> 37 public abstract RouteValueDictionary Default { 38 get; 39 } 40 41 /// <summary> 42////拘束 43 /// </summary> 44 public abstract RouteValueDictionary Constraint { 45 get; 46 } 47 48 /// <summary> 49 /// 50 /// </summary> 51 /// <param name="routes"></param> 52 /// <param name="item"></param> 53 public static void Map(RouteCollection routes, RouteItemBase item) { 54 routes.MapPageRoute(item.RouteName , item.RouteUrl, item.PhyicalUrl, false, item.Default, item.Constraint); 55 } 56 57 /// <summary> 58 /// 59 /// </summary> 60 /// <returns></returns> 61 public abstract object Format(); 62 } 63 }     HotelInfoRoute 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Web.Routing; 6 using XXX.Frameworks.Const; 7 using XXX.Frameworks.Route; 8 9 namespace Hotel.Online.Route { 10 11 /// <summary> 12 /// 13 /// </summary> 14 public class HotelInfoRoute : RouteItemBase { 15 16 public object Hid { 17 get; 18 set; 19 } 20 21 public DateTime Ds { 22 get; 23 set; 24 } 25 26 public DateTime De { 27 get; 28 set; 29 } 30 31 32 33 #region RouteItemBase 34 public override string RouteName { 35 get { 36 return RouteNames.HotelInfo.ToString(); 37 } 38 } 39 40 41 public override string RouteUrl { 42 get { 43 return "HotelInfo/{hid}/{ds}/{de}"; 44 } 45 } 46 47 public override string PhyicalUrl { 48 get { 49 return "~/HotelInfo.aspx"; 50 } 51 } 52 53 public override RouteValueDictionary Default { 54 get { 55 return new RouteValueDictionary(new { 56 Ds = DateTime.Now.AddDays(1).ToString(DateFormat.Date), 57 De = DateTime.Now.AddDays(2).ToString(DateFormat.Date) 58 }); 59 } 60 } 61 62 public override RouteValueDictionary Constraint { 63 get { 64 return new RouteValueDictionary(new { 65 Hid = @"\d+", 66 Ds = @"\d{4}-\d{2}-\d{2}", 67 De = @"\d{4}-\d{2}-\d{2}" 68 }); 69 } 70 } 71 72 public override object Format() { 73 return new { 74 Hid = this.Hid, 75 Ds = this.Ds.ToString(DateFormat.Date), 76 De = this.De.ToString(DateFormat.Date) 77 }; 78 } 79 #endregion 80 } 81}注意HotelInfoRouteのRouteUrl,HotelInfo/{hid}/{ds}/{de}Hid,ds,de是鲁丁格的电脑,大文字和小文字没有区别.因为同时,我同时定义了Hid,Ds,De的几个属性(注意:与卢丁格帕拉梅特完全相同,分别大文字和小文字),这些几个属性都有用取得页面取得Route Url和卢丁格帕拉梅特,面试说。    GlobalではRouteHelper.AutoLoadRoutes在某Assembly的下,自动发现从RouteItemBase传承的所有的级别,因为在现在的路线网上自动登记,所以追加路线时必须手动改变Global.  1 void Map(RouteCollection routes) { 2 routes.RouteExistingFiles = true; 3 routes.Ignore("{resource}.axd/{*pathInfo}"); 4 routes.Ignore("{*AllRes}", new { 5 AllRes = @".*?\.(?!aspx)(.*)" 6 }); 7 8 //RouteItemBase.Map(routes, new HotelInfoRoute()); 9 RouteHelper.AutoLoadRoutes(routes, typeof(HotelInfoRoute).Assembly); 10 } 11 12 void Application_Start(object sender, EventArgs e) { 13 Map(RouteTable.Routes); 14 …. 15 16 …. 页内var routeData=this.Page.RouteData.Values;var HotelID = (routeData["hid"] ?? "").ToString().ToInt(-110),如果这样写的话,如果路特电脑{hid}变成{hoteliD}的话,你在页上还用hid.当然没有价值。どうすればいいですか.强烈的类型可以仔细避免这个问题.你怎么用?Page.RouteData.Values是RouteValueDictionary类型,由IDictionary继承,对IDctionary进行了扩张方法.1 public static T ToEntity<T>(this IDictionary<string, object> dict) where T : new() { 2 var t = typeof(T); 3 var ps = t.GetProperties(); 4 T tmp = new T(); 5 6 foreach (var p in ps) { 7 if (!p.CanWrite) 8 continue; 9 //var v = dict.Get(p.Name); 10 if (dict.ContainsKey(p.Name)) { 11 p.SetValue(tmp, Convert.ChangeType(dict[p.Name], p.PropertyType), null); 12 } 13 } 14 return tmp; 15}接下来,this.RouteData = this.Page.RouteData.Values.ToEntity(); 抽出这个页面的路线电视台的var HotelID直接等于RouteData.取得Hid的路线后的亚德雷斯,如下简略化。  1 public static string GetRoutedUrl<T>(T routeData) 2 where T : RouteItemBase { 3 return RouteTable.Routes.GetVirtualPath(HttpContextHelper.Current.Request.RequestContext, routeData.RouteName.ToString(), new RouteValueDictionary( 4 routeData.Format() 5 )).VirtualPath; 6}HttpContextHelper的定義是XXX.Frameworks.Extends.在HttpContextHelper中被定义,为什么不使用HttpContext?因为在优衣测试中有问题。return RouteHelper.GetRoutedUrl(new HotelInfoRoute() { Hid = hotelID.ToString(), Ds = this.BeginDate, De = this.EndDate }); 果然是强烈的类型,我不会害怕重新。我把亚德雷斯放进新的亚德雷斯HotelInfo.aspxというAddressは必ず被检索发动机收录されていますが、如果现在废弃这样的Address,那嚒对SEO和用户来说最令人期待.如果把古的阿德雷斯301作为新的阿德雷斯,SEO和用户没有什么影响.为了达成这个效果,我追加了方法。1 public static void RedirectToRouted(this Page page, string routeName) { 2 if (page.RouteData.Route == null) { 3 var context = HttpContextHelper.Current; 4 var querys = context.Request.QueryString; 5 var keys = querys.Cast<string>().ToList(); 6 7 RouteValueDictionary datas = new RouteValueDictionary(); 8 keys.ForEach((k) => { 9 datas.Add(k, querys[k]); 10 }); 11 12 var vp = RouteTable.Routes.GetVirtualPath(context.Request.RequestContext, routeName, new RouteValueDictionary(datas)); 13 context.Response.Status = "301 Moved Permanently"; 14 context.Response.RedirectLocation = vp.VirtualPath; 15 context.Response.End(); 16 } 17}有必要改变古的艺术家,如下追加.1 protected override void OnPreInit(EventArgs e){ 2 this.Page.RedirectToRouted( RouteNames.HotelInfo.ToString() ); 3 4 base.OnPreInit(e); 5 }