• 我的NopCommerce之旅(8): 路由分析


    一、导图和基础介绍

    本文主要介绍NopCommerce的路由机制,网上有一篇不错的文章,有兴趣的可以看看NopCommerce源码架构详解--对seo友好Url的路由机制实现源码分析

    SEO,Search Engine Optimization,中文叫做搜索引擎优化,主要是为了提高网站关键词排名,提高访问量。SEO是一个很广的话题,我们这里主要了解NopCommerce的友好Url机制(它是实现SEO的一个步骤)。

    二、承上启下

    我的NopCommerce之旅(6): 应用启动中介绍在应用启动时,进行了常见的MVC物件的注册,包括Area、Route。这里通过调用公共接口方法,调用了所有实现了公共接口的类,实现对所有路由的注册。

    1             //Registering some regular mvc stuff
    2             AreaRegistration.RegisterAllAreas();
    3             RegisterRoutes(RouteTable.Routes);
    1             //register custom routes (plugins, etc)
    2             var routePublisher = EngineContext.Current.Resolve<IRoutePublisher>();
    3             routePublisher.RegisterRoutes(routes);
     1         /// <summary>
     2         /// Register routes
     3         /// </summary>
     4         /// <param name="routes">Routes</param>
     5         public virtual void RegisterRoutes(RouteCollection routes)
     6         {
     7             var routeProviderTypes = typeFinder.FindClassesOfType<IRouteProvider>();
     8             var routeProviders = new List<IRouteProvider>();
     9             foreach (var providerType in routeProviderTypes)
    10             {
    11                 //Ignore not installed plugins
    12                 var plugin = FindPlugin(providerType);
    13                 if (plugin != null && !plugin.Installed)
    14                     continue;
    15 
    16                 var provider = Activator.CreateInstance(providerType) as IRouteProvider;
    17                 routeProviders.Add(provider);
    18             }
    19             routeProviders = routeProviders.OrderByDescending(rp => rp.Priority).ToList();
    20             routeProviders.ForEach(rp => rp.RegisterRoutes(routes));//根据顺序,注册路由
    21         }

    三、公共接口

    Nop.Web.Framework.Mvc.Routes.IRouteProvider,核心路由、友好路由以及Plugin等实现该接口进行路由注册。

    Nop.Web.Framework.Mvc.Routes.IRoutePublisher

    四、注册实现

      1.核心路由注册,包括首页、部件、登录注册、购物车等,代码位置为Nop.Web.Infrastructure.RouteProvider。

      1         public void RegisterRoutes(RouteCollection routes)
      2         {
      3             //We reordered our routes so the most used ones are on top. It can improve performance.
      4 
      5             //home page
      6             routes.MapLocalizedRoute("HomePage",
      7                             "",
      8                             new { controller = "Home", action = "Index" },
      9                             new[] { "Nop.Web.Controllers" });
     10 
     11             //widgets
     12             //we have this route for performance optimization because named routes are MUCH faster than usual Html.Action(...)
     13             //and this route is highly used
     14             routes.MapRoute("WidgetsByZone",
     15                             "widgetsbyzone/",
     16                             new { controller = "Widget", action = "WidgetsByZone" },
     17                             new[] { "Nop.Web.Controllers" });
     18 
     19             //login
     20             routes.MapLocalizedRoute("Login",
     21                             "login/",
     22                             new { controller = "Customer", action = "Login" },
     23                             new[] { "Nop.Web.Controllers" });
     24             //register
     25             routes.MapLocalizedRoute("Register",
     26                             "register/",
     27                             new { controller = "Customer", action = "Register" },
     28                             new[] { "Nop.Web.Controllers" });
     29             //logout
     30             routes.MapLocalizedRoute("Logout",
     31                             "logout/",
     32                             new { controller = "Customer", action = "Logout" },
     33                             new[] { "Nop.Web.Controllers" });
     34 
     35             //shopping cart
     36             routes.MapLocalizedRoute("ShoppingCart",
     37                             "cart/",
     38                             new { controller = "ShoppingCart", action = "Cart" },
     39                             new[] { "Nop.Web.Controllers" });
     40             //wishlist
     41             routes.MapLocalizedRoute("Wishlist",
     42                             "wishlist/{customerGuid}",
     43                             new { controller = "ShoppingCart", action = "Wishlist", customerGuid = UrlParameter.Optional },
     44                             new[] { "Nop.Web.Controllers" });
     45 
     46             //customer account links
     47             routes.MapLocalizedRoute("CustomerInfo",
     48                             "customer/info",
     49                             new { controller = "Customer", action = "Info" },
     50                             new[] { "Nop.Web.Controllers" });
     51             ...
     52 
     53             //contact us
     54             routes.MapLocalizedRoute("ContactUs",
     55                             "contactus",
     56                             new { controller = "Common", action = "ContactUs" },
     57                             new[] { "Nop.Web.Controllers" });
     58             //sitemap
     59             routes.MapLocalizedRoute("Sitemap",
     60                             "sitemap",
     61                             new { controller = "Common", action = "Sitemap" },
     62                             new[] { "Nop.Web.Controllers" });
     63 
     64             //product search
     65             routes.MapLocalizedRoute("ProductSearch",
     66                             "search/",
     67                             new { controller = "Catalog", action = "Search" },
     68                             new[] { "Nop.Web.Controllers" });
     69             routes.MapLocalizedRoute("ProductSearchAutoComplete",
     70                             "catalog/searchtermautocomplete",
     71                             new { controller = "Catalog", action = "SearchTermAutoComplete" },
     72                             new[] { "Nop.Web.Controllers" });
     73 
     74             //change currency (AJAX link)
     75             routes.MapLocalizedRoute("ChangeCurrency",
     76                             "changecurrency/{customercurrency}",
     77                             new { controller = "Common", action = "SetCurrency" },
     78                             new { customercurrency = @"d+" },
     79                             new[] { "Nop.Web.Controllers" });
     80             //change language (AJAX link)
     81             routes.MapLocalizedRoute("ChangeLanguage",
     82                             "changelanguage/{langid}",
     83                             new { controller = "Common", action = "SetLanguage" },
     84                             new { langid = @"d+" },
     85                             new[] { "Nop.Web.Controllers" });
     86             //change tax (AJAX link)
     87             routes.MapLocalizedRoute("ChangeTaxType",
     88                             "changetaxtype/{customertaxtype}",
     89                             new { controller = "Common", action = "SetTaxType" },
     90                             new { customertaxtype = @"d+" },
     91                             new[] { "Nop.Web.Controllers" });
     92 
     93             //recently viewed products
     94             routes.MapLocalizedRoute("RecentlyViewedProducts",
     95                             "recentlyviewedproducts/",
     96                             new { controller = "Product", action = "RecentlyViewedProducts" },
     97                             new[] { "Nop.Web.Controllers" });
     98             //new products
     99             routes.MapLocalizedRoute("NewProducts",
    100                             "newproducts/",
    101                             new { controller = "Product", action = "NewProducts" },
    102                             new[] { "Nop.Web.Controllers" });
    103             //blog
    104             routes.MapLocalizedRoute("Blog",
    105                             "blog",
    106                             new { controller = "Blog", action = "List" },
    107                             new[] { "Nop.Web.Controllers" });
    108             //news
    109             routes.MapLocalizedRoute("NewsArchive",
    110                             "news",
    111                             new { controller = "News", action = "List" },
    112                             new[] { "Nop.Web.Controllers" });
    113 
    114             //forum
    115             routes.MapLocalizedRoute("Boards",
    116                             "boards",
    117                             new { controller = "Boards", action = "Index" },
    118                             new[] { "Nop.Web.Controllers" });
    119 
    120             //compare products
    121             routes.MapLocalizedRoute("CompareProducts",
    122                             "compareproducts/",
    123                             new { controller = "Product", action = "CompareProducts" },
    124                             new[] { "Nop.Web.Controllers" });
    125 
    126             //product tags
    127             routes.MapLocalizedRoute("ProductTagsAll",
    128                             "producttag/all/",
    129                             new { controller = "Catalog", action = "ProductTagsAll" },
    130                             new[] { "Nop.Web.Controllers" });
    131 
    132             //manufacturers
    133             routes.MapLocalizedRoute("ManufacturerList",
    134                             "manufacturer/all/",
    135                             new { controller = "Catalog", action = "ManufacturerAll" },
    136                             new[] { "Nop.Web.Controllers" });
    137             //vendors
    138             routes.MapLocalizedRoute("VendorList",
    139                             "vendor/all/",
    140                             new { controller = "Catalog", action = "VendorAll" },
    141                             new[] { "Nop.Web.Controllers" });
    142 
    143 
    144             //add product to cart (without any attributes and options). used on catalog pages.
    145             routes.MapLocalizedRoute("AddProductToCart-Catalog",
    146                             "addproducttocart/catalog/{productId}/{shoppingCartTypeId}/{quantity}",
    147                             new { controller = "ShoppingCart", action = "AddProductToCart_Catalog" },
    148                             new { productId = @"d+", shoppingCartTypeId = @"d+", quantity = @"d+" },
    149                             new[] { "Nop.Web.Controllers" });
    150             //add product to cart (with attributes and options). used on the product details pages.
    151             routes.MapLocalizedRoute("AddProductToCart-Details",
    152                             "addproducttocart/details/{productId}/{shoppingCartTypeId}",
    153                             new { controller = "ShoppingCart", action = "AddProductToCart_Details" },
    154                             new { productId = @"d+", shoppingCartTypeId = @"d+" },
    155                             new[] { "Nop.Web.Controllers" });
    156 
    157             //product tags
    158             routes.MapLocalizedRoute("ProductsByTag",
    159                             "producttag/{productTagId}/{SeName}",
    160                             new { controller = "Catalog", action = "ProductsByTag", SeName = UrlParameter.Optional },
    161                             new { productTagId = @"d+" },
    162                             new[] { "Nop.Web.Controllers" });
    163             //comparing products
    164             routes.MapLocalizedRoute("AddProductToCompare",
    165                             "compareproducts/add/{productId}",
    166                             new { controller = "Product", action = "AddProductToCompareList" },
    167                             new { productId = @"d+" },
    168                             new[] { "Nop.Web.Controllers" });
    169             //product email a friend
    170             routes.MapLocalizedRoute("ProductEmailAFriend",
    171                             "productemailafriend/{productId}",
    172                             new { controller = "Product", action = "ProductEmailAFriend" },
    173                             new { productId = @"d+" },
    174                             new[] { "Nop.Web.Controllers" });
    175             //reviews
    176             routes.MapLocalizedRoute("ProductReviews",
    177                             "productreviews/{productId}",
    178                             new { controller = "Product", action = "ProductReviews" },
    179                             new[] { "Nop.Web.Controllers" });
    180             //back in stock notifications
    181             routes.MapLocalizedRoute("BackInStockSubscribePopup",
    182                             "backinstocksubscribe/{productId}",
    183                             new { controller = "BackInStockSubscription", action = "SubscribePopup" },
    184                             new { productId = @"d+" },
    185                             new[] { "Nop.Web.Controllers" });
    186             //downloads
    187             routes.MapRoute("GetSampleDownload",
    188                             "download/sample/{productid}",
    189                             new { controller = "Download", action = "Sample" },
    190                             new { productid = @"d+" },
    191                             new[] { "Nop.Web.Controllers" });
    192 
    193 
    194 
    195             //checkout pages
    196             routes.MapLocalizedRoute("Checkout",
    197                             "checkout/",
    198                             new { controller = "Checkout", action = "Index" },
    199                             new[] { "Nop.Web.Controllers" });
    200             ...
    201 
    202             //subscribe newsletters
    203             routes.MapLocalizedRoute("SubscribeNewsletter",
    204                             "subscribenewsletter",
    205                             new { controller = "Newsletter", action = "SubscribeNewsletter" },
    206                             new[] { "Nop.Web.Controllers" });
    207 
    208             //email wishlist
    209             routes.MapLocalizedRoute("EmailWishlist",
    210                             "emailwishlist",
    211                             new { controller = "ShoppingCart", action = "EmailWishlist" },
    212                             new[] { "Nop.Web.Controllers" });
    213 
    214             //login page for checkout as guest
    215             routes.MapLocalizedRoute("LoginCheckoutAsGuest",
    216                             "login/checkoutasguest",
    217                             new { controller = "Customer", action = "Login", checkoutAsGuest = true },
    218                             new[] { "Nop.Web.Controllers" });
    219             //register result page
    220             routes.MapLocalizedRoute("RegisterResult",
    221                             "registerresult/{resultId}",
    222                             new { controller = "Customer", action = "RegisterResult" },
    223                             new { resultId = @"d+" },
    224                             new[] { "Nop.Web.Controllers" });
    225             //check username availability
    226             routes.MapLocalizedRoute("CheckUsernameAvailability",
    227                             "customer/checkusernameavailability",
    228                             new { controller = "Customer", action = "CheckUsernameAvailability" },
    229                             new[] { "Nop.Web.Controllers" });
    230 
    231             //passwordrecovery
    232             routes.MapLocalizedRoute("PasswordRecovery",
    233                             "passwordrecovery",
    234                             new { controller = "Customer", action = "PasswordRecovery" },
    235                             new[] { "Nop.Web.Controllers" });
    236             //password recovery confirmation
    237             routes.MapLocalizedRoute("PasswordRecoveryConfirm",
    238                             "passwordrecovery/confirm",
    239                             new { controller = "Customer", action = "PasswordRecoveryConfirm" },                            
    240                             new[] { "Nop.Web.Controllers" });
    241 
    242             //topics
    243             routes.MapLocalizedRoute("TopicPopup",
    244                             "t-popup/{SystemName}",
    245                             new { controller = "Topic", action = "TopicDetailsPopup" },
    246                             new[] { "Nop.Web.Controllers" });
    247             
    248             //blog
    249             routes.MapLocalizedRoute("BlogByTag",
    250                             "blog/tag/{tag}",
    251                             new { controller = "Blog", action = "BlogByTag" },
    252                             new[] { "Nop.Web.Controllers" });
    253             routes.MapLocalizedRoute("BlogByMonth",
    254                             "blog/month/{month}",
    255                             new { controller = "Blog", action = "BlogByMonth" },
    256                             new[] { "Nop.Web.Controllers" });
    257             //blog RSS
    258             routes.MapLocalizedRoute("BlogRSS",
    259                             "blog/rss/{languageId}",
    260                             new { controller = "Blog", action = "ListRss" },
    261                             new { languageId = @"d+" },
    262                             new[] { "Nop.Web.Controllers" });
    263 
    264             //news RSS
    265             routes.MapLocalizedRoute("NewsRSS",
    266                             "news/rss/{languageId}",
    267                             new { controller = "News", action = "ListRss" },
    268                             new { languageId = @"d+" },
    269                             new[] { "Nop.Web.Controllers" });
    270 
    271             //set review helpfulness (AJAX link)
    272             routes.MapRoute("SetProductReviewHelpfulness",
    273                             "setproductreviewhelpfulness",
    274                             new { controller = "Product", action = "SetProductReviewHelpfulness" },
    275                             new[] { "Nop.Web.Controllers" });
    276 
    277             //customer account links
    278             routes.MapLocalizedRoute("CustomerReturnRequests",
    279                             "returnrequest/history",
    280                             new { controller = "ReturnRequest", action = "CustomerReturnRequests" },
    281                             new[] { "Nop.Web.Controllers" });
    282             ...
    283             //customer profile page
    284             routes.MapLocalizedRoute("CustomerProfile",
    285                             "profile/{id}",
    286                             new { controller = "Profile", action = "Index" },
    287                             new { id = @"d+" },
    288                             new[] { "Nop.Web.Controllers" });
    289             routes.MapLocalizedRoute("CustomerProfilePaged",
    290                             "profile/{id}/page/{page}",
    291                             new { controller = "Profile", action = "Index" },
    292                             new { id = @"d+", page = @"d+" },
    293                             new[] { "Nop.Web.Controllers" });
    294 
    295             //orders
    296             routes.MapLocalizedRoute("OrderDetails",
    297                             "orderdetails/{orderId}",
    298                             new { controller = "Order", action = "Details" },
    299                             new { orderId = @"d+" },
    300                             new[] { "Nop.Web.Controllers" });
    301             ...
    302             //order downloads
    303             routes.MapRoute("GetDownload",
    304                             "download/getdownload/{orderItemId}/{agree}",
    305                             new { controller = "Download", action = "GetDownload", agree = UrlParameter.Optional },
    306                             new { orderItemId = new GuidConstraint(false) },
    307                             new[] { "Nop.Web.Controllers" });
    308             ...
    309 
    310             //contact vendor
    311             routes.MapLocalizedRoute("ContactVendor",
    312                             "contactvendor/{vendorId}",
    313                             new { controller = "Common", action = "ContactVendor" },
    314                             new[] { "Nop.Web.Controllers" });
    315             //apply for vendor account
    316             routes.MapLocalizedRoute("ApplyVendorAccount",
    317                             "vendor/apply",
    318                             new { controller = "Vendor", action = "ApplyVendor" },
    319                             new[] { "Nop.Web.Controllers" });
    320 
    321             //poll vote AJAX link
    322             routes.MapLocalizedRoute("PollVote",
    323                             "poll/vote",
    324                             new { controller = "Poll", action = "Vote" },
    325                             new[] { "Nop.Web.Controllers" });
    326 
    327             //comparing products
    328             routes.MapLocalizedRoute("RemoveProductFromCompareList",
    329                             "compareproducts/remove/{productId}",
    330                             new { controller = "Product", action = "RemoveProductFromCompareList" },
    331                             new[] { "Nop.Web.Controllers" });
    332             routes.MapLocalizedRoute("ClearCompareList",
    333                             "clearcomparelist/",
    334                             new { controller = "Product", action = "ClearCompareList" },
    335                             new[] { "Nop.Web.Controllers" });
    336 
    337             //new RSS
    338             routes.MapLocalizedRoute("NewProductsRSS",
    339                             "newproducts/rss",
    340                             new { controller = "Product", action = "NewProductsRss" },
    341                             new[] { "Nop.Web.Controllers" });
    342             
    343             //get state list by country ID  (AJAX link)
    344             routes.MapRoute("GetStatesByCountryId",
    345                             "country/getstatesbycountryid/",
    346                             new { controller = "Country", action = "GetStatesByCountryId" },
    347                             new[] { "Nop.Web.Controllers" });
    348 
    349             //EU Cookie law accept button handler (AJAX link)
    350             routes.MapRoute("EuCookieLawAccept",
    351                             "eucookielawaccept",
    352                             new { controller = "Common", action = "EuCookieLawAccept" },
    353                             new[] { "Nop.Web.Controllers" });
    354 
    355             //authenticate topic AJAX link
    356             routes.MapLocalizedRoute("TopicAuthenticate",
    357                             "topic/authenticate",
    358                             new { controller = "Topic", action = "Authenticate" },
    359                             new[] { "Nop.Web.Controllers" });
    360 
    361             //product attributes with "upload file" type
    362             routes.MapLocalizedRoute("UploadFileProductAttribute",
    363                             "uploadfileproductattribute/{attributeId}",
    364                             new { controller = "ShoppingCart", action = "UploadFileProductAttribute" },
    365                             new { attributeId = @"d+" },
    366                             new[] { "Nop.Web.Controllers" });
    367             //checkout attributes with "upload file" type
    368             routes.MapLocalizedRoute("UploadFileCheckoutAttribute",
    369                             "uploadfilecheckoutattribute/{attributeId}",
    370                             new { controller = "ShoppingCart", action = "UploadFileCheckoutAttribute" },
    371                             new { attributeId = @"d+" },
    372                             new[] { "Nop.Web.Controllers" });
    373             
    374             //forums
    375             routes.MapLocalizedRoute("ActiveDiscussions",
    376                             "boards/activediscussions",
    377                             new { controller = "Boards", action = "ActiveDiscussions" },
    378                             new[] { "Nop.Web.Controllers" });
    379             ...
    380 
    381             //private messages
    382             routes.MapLocalizedRoute("PrivateMessages",
    383                             "privatemessages/{tab}",
    384                             new { controller = "PrivateMessages", action = "Index", tab = UrlParameter.Optional },
    385                             new[] { "Nop.Web.Controllers" });
    386             ...
    387 
    388             //activate newsletters
    389             routes.MapLocalizedRoute("NewsletterActivation",
    390                             "newsletter/subscriptionactivation/{token}/{active}",
    391                             new { controller = "Newsletter", action = "SubscriptionActivation" },
    392                             new { token = new GuidConstraint(false) },
    393                             new[] { "Nop.Web.Controllers" });
    394 
    395             //robots.txt
    396             routes.MapRoute("robots.txt",
    397                             "robots.txt",
    398                             new { controller = "Common", action = "RobotsTextFile" },
    399                             new[] { "Nop.Web.Controllers" });
    400 
    401             //sitemap (XML)
    402             routes.MapLocalizedRoute("sitemap.xml",
    403                             "sitemap.xml",
    404                             new { controller = "Common", action = "SitemapXml" },
    405                             new[] { "Nop.Web.Controllers" });
    406 
    407             //store closed
    408             routes.MapLocalizedRoute("StoreClosed",
    409                             "storeclosed",
    410                             new { controller = "Common", action = "StoreClosed" },
    411                             new[] { "Nop.Web.Controllers" });
    412 
    413             //install
    414             routes.MapRoute("Installation",
    415                             "install",
    416                             new { controller = "Install", action = "Index" },
    417                             new[] { "Nop.Web.Controllers" });
    418             
    419             //page not found
    420             routes.MapLocalizedRoute("PageNotFound",
    421                             "page-not-found",
    422                             new { controller = "Common", action = "PageNotFound" },
    423                             new[] { "Nop.Web.Controllers" });
    424         }
    View Code

      2.SEO友好路由注册,包括产品、种类、生产商、供应商、新闻、博客、主题等具体信息的路由,代码位置为Nop.Web.Infrastructure.GenericUrlRouteProvider。

      经过优化过的友好Url为http://localhost/apple-macbook-pro-13-inch,而经过解析后访问的实际http://localhost/Product/ProductDetails/{productId}

     1         public void RegisterRoutes(RouteCollection routes)
     2         {
     3             //generic URLs
     4             routes.MapGenericPathRoute("GenericUrl",
     5                                        "{generic_se_name}",
     6                                        new {controller = "Common", action = "GenericUrl"},
     7                                        new[] {"Nop.Web.Controllers"});
     8 
     9             //define this routes to use in UI views (in case if you want to customize some of them later)
    10             routes.MapLocalizedRoute("Product",
    11                                      "{SeName}",
    12                                      new { controller = "Product", action = "ProductDetails" },
    13                                      new[] {"Nop.Web.Controllers"});
    14 
    15             routes.MapLocalizedRoute("Category",
    16                             "{SeName}",
    17                             new { controller = "Catalog", action = "Category" },
    18                             new[] { "Nop.Web.Controllers" });
    19 
    20             routes.MapLocalizedRoute("Manufacturer",
    21                             "{SeName}",
    22                             new { controller = "Catalog", action = "Manufacturer" },
    23                             new[] { "Nop.Web.Controllers" });
    24 
    25             routes.MapLocalizedRoute("Vendor",
    26                             "{SeName}",
    27                             new { controller = "Catalog", action = "Vendor" },
    28                             new[] { "Nop.Web.Controllers" });
    29             
    30             routes.MapLocalizedRoute("NewsItem",
    31                             "{SeName}",
    32                             new { controller = "News", action = "NewsItem" },
    33                             new[] { "Nop.Web.Controllers" });
    34 
    35             routes.MapLocalizedRoute("BlogPost",
    36                             "{SeName}",
    37                             new { controller = "Blog", action = "BlogPost" },
    38                             new[] { "Nop.Web.Controllers" });
    39 
    40             routes.MapLocalizedRoute("Topic",
    41                             "{SeName}",
    42                             new { controller = "Topic", action = "TopicDetails" },
    43                             new[] { "Nop.Web.Controllers" });
    44 
    45 
    46 
    47             //the last route. it's used when none of registered routes could be used for the current request
    48             //but it this case we cannot process non-registered routes (/controller/action)
    49             //routes.MapLocalizedRoute(
    50             //    "PageNotFound-Wildchar",
    51             //    "{*url}",
    52             //    new { controller = "Common", action = "PageNotFound" },
    53             //    new[] { "Nop.Web.Controllers" });
    54         }
    View Code

    五、友好Url解析

      NopCommerce中通过继承Route类,重写RouteData GetRouteData(HttpContextBase httpContext)方法来获取真正路由。代码位置为Nop.Web.Framework.Localization.LocalizedRoute和Nop.Web.Framework.Seo.GenericPathRoute。

      GenericPathRoute类的GetRouteData()方法是我们要讲的重点,它实现了友好Url的解析。下面是方法代码的分析:

      1.获取Url的标识值。

        获取请求中generic_se_name的值。

     1         public override RouteData GetRouteData(HttpContextBase httpContext)
     2         {
     3             RouteData data = base.GetRouteData(httpContext);
     4             if (data != null && DataSettingsHelper.DatabaseIsInstalled())
     5             {
     6                 var urlRecordService = EngineContext.Current.Resolve<IUrlRecordService>();
     7                 var slug = data.Values["generic_se_name"] as string;//获取标识值,如"apple-macbook-pro-13-inch" 8                 ...
     9             }
    10             return data;
    11         }

      2.根据标识解析实际路由信息

        2.1 从缓存中读取该标识关联的值,值包括访问的controller和Id

    1         public override RouteData GetRouteData(HttpContextBase httpContext)
    2         {
    3             ...
    4                 var slug = data.Values["generic_se_name"] as string;
    5                 //performance optimization.
    6                 //we load a cached verion here. it reduces number of SQL requests for each page load
    7                 var urlRecord = urlRecordService.GetBySlugCached(slug);
    8             ...
    9         }
     1         /// <summary>
     2         /// Find URL record (cached version).
     3         /// This method works absolutely the same way as "GetBySlug" one but caches the results.
     4         /// Hence, it's used only for performance optimization in public store
     5         /// </summary>
     6         /// <param name="slug">Slug</param>
     7         /// <returns>Found URL record</returns>
     8         public virtual UrlRecordForCaching GetBySlugCached(string slug)
     9         {
    10             if (String.IsNullOrEmpty(slug))
    11                 return null;
    12 
    13             if (_localizationSettings.LoadAllUrlRecordsOnStartup)
    14             {
    15                 //load all records (we know they are cached)
    16                 var source = GetAllUrlRecordsCached();
    17                 var query = from ur in source
    18                             where ur.Slug.Equals(slug, StringComparison.InvariantCultureIgnoreCase)
    19                             select ur;
    20                 var urlRecordForCaching = query.FirstOrDefault();
    21                 return urlRecordForCaching;
    22             }
    23 
    24             //gradual loading
    25             string key = string.Format(URLRECORD_BY_SLUG_KEY, slug);
    26             return _cacheManager.Get(key, () =>
    27             {
    28                 var urlRecord = GetBySlug(slug);//从数据库读取
    29                 if (urlRecord == null)
    30                     return null;
    31 
    32                 var urlRecordForCaching = Map(urlRecord);
    33                 return urlRecordForCaching;
    34             });
    35         }

        2.2 若缓存中不存在则读取数据库数据,数据库表为[dbo].[UrlRecord]

     1         /// <summary>
     2         /// Find URL record
     3         /// </summary>
     4         /// <param name="slug">Slug</param>
     5         /// <returns>Found URL record</returns>
     6         public virtual UrlRecord GetBySlug(string slug)
     7         {
     8             if (String.IsNullOrEmpty(slug))
     9                 return null;
    10 
    11             var query = from ur in _urlRecordRepository.Table
    12                         where ur.Slug == slug
    13                         select ur;
    14             var urlRecord = query.FirstOrDefault();
    15             return urlRecord;
    16         }

        2.3 根据读取的值的EntityName,返回路由信息。

     1                 //process URL
     2                 switch (urlRecord.EntityName.ToLowerInvariant())
     3                 {
     4                     case "product":
     5                         {
     6                             data.Values["controller"] = "Product";
     7                             data.Values["action"] = "ProductDetails";
     8                             data.Values["productid"] = urlRecord.EntityId;
     9                             data.Values["SeName"] = urlRecord.Slug;
    10                     ...

      3.访问路由信息

  • 相关阅读:
    点击按钮,回到页面顶部的5种写法
    node知识积累
    Python3基础 str ljust-rjust-center 左、右对齐 居中
    Python3基础 str : 对字符串进行切片
    Python3基础 str : 字符串的逆序
    Python3基础 str __add__ 拼接,原字符串不变
    Python3基础 运算 加减乘除、取余数
    Python3基础 只有int类型,没有long类型
    Python3基础 complex 声明复数
    Python3基础 complex real imag __abs__ 取复数的实部 虚部 模
  • 原文地址:https://www.cnblogs.com/devilsky/p/5368570.html
Copyright © 2020-2023  润新知