首页 技术 正文
技术 2022年11月8日
0 收藏 351 点赞 1,207 浏览 34934 个字

在Global.asax,Application_Start()方法中会进行路由注册,代码如下。

        public static void RegisterRoutes(RouteCollection routes)         {             routes.IgnoreRoute("favicon.ico");             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");             //register custom routes (plugins, etc)             var routePublisher = EngineContext.Current.Resolve<IRoutePublisher>();             routePublisher.RegisterRoutes(routes);             routes.MapRoute(                 "Default", // Route name                 "{controller}/{action}/{id}", // URL with parameters                 new { controller = "Home", action = "Index", id = UrlParameter.Optional },                 new[] { "Nop.Web.Controllers" }             );         }

我们会发现调用了IRutePublisher接口,该接口由Nop.Web.Framework.Mvc.Routes.RoutePublisher类实现。

并通过RegisterRoutes(RouteCollection routes)方法进行路由注册。代码如下:

   /// <summary>         /// Register routes         /// </summary>         /// <param name="routes">Routes</param>         public virtual void RegisterRoutes(RouteCollection routes)         {             //ITypeFinder接口获取所有IRouteProvider接口实现类的Type对象             var routeProviderTypes = typeFinder.FindClassesOfType<IRouteProvider>();             var routeProviders = new List<IRouteProvider>();             foreach (var providerType in routeProviderTypes)             {                 //Ignore not installed plugins                 var plugin = FindPlugin(providerType);//PluginManager.ReferencedPlugins中查找该Type对象                 if (plugin != null && !plugin.Installed)//插件不为空未安装则跳出本次循环                     continue;                 var provider = Activator.CreateInstance(providerType) as IRouteProvider;//实例化IRouteProvider接口对象                 routeProviders.Add(provider);             }             routeProviders = routeProviders.OrderByDescending(rp => rp.Priority).ToList();//排序             routeProviders.ForEach(rp => rp.RegisterRoutes(routes));//遍历并调用RegisterRoutes(routes)进行路由注册         }

该方法做了如下工作:

第一步:通过ITyperFinder接口找到所有实现了IRouteProvider接口的类类型。保存在routeProviderTypes集合中

第二步:遍历routeProviderTypes集合,通过PluginManager类找到未安装IRouteProvider类类型。并从routeProviderTypes集合中排除掉。

第三步:实例化IRouteProvider实现类。

第四部:调用IRouteProvider实现类RegisterRoutes(routes)方法进行路由注册。

下图为主要接口之间的调用关系

通过上述分析nop路由注册主要是通过IRouteProvider接口实现的,现在我们看看项目中实现该接口的类都有哪些。

下图红色是在Nop.Web项目中,其他都是在nop插件中。

接下来我们看下路由的注册顺序如下图,我们看到最先匹配的Nop.Web.Infrastructure.RouteProvider中的路由注册。

启用支持多语言的SEO友好链接

nop支持SEO友好链接,管理后台->设置管理->综合设置->启用支持多语言的SEO友好链接 选中就可以支持了。

启用后URL格式为: http://www.yourStore.com/en/ 或 http://www.yourStore.com/zh/ (SEO比较友好)

那该功能怎么实现的呢?接下来我们看看nop是如何通过路由扩展实现的。

(Nop.Web.Framework.WebWorkContext在多语言中也会用到,这里先不讲它,我们只说路由)

我们先看下Nop.Web.Infrastructure.RouteProvider中的路由注册代码

 using System.Web.Mvc; using System.Web.Routing; using Nop.Web.Framework.Localization; using Nop.Web.Framework.Mvc.Routes; namespace Nop.Web.Infrastructure {     public partial class RouteProvider : IRouteProvider     {         public void RegisterRoutes(RouteCollection routes)         {             //We reordered our routes so the most used ones are on top. It can improve performance.             //本地化路由             //home page             routes.MapLocalizedRoute("HomePage",                             "",                             new { controller = "Home", action = "Index" },                             new[] { "Nop.Web.Controllers" });             //widgets             //we have this route for performance optimization because named routes are MUCH faster than usual Html.Action(...)             //and this route is highly used             routes.MapRoute("WidgetsByZone",                             "widgetsbyzone/",                             new { controller = "Widget", action = "WidgetsByZone" },                             new[] { "Nop.Web.Controllers" });             //login             routes.MapLocalizedRoute("Login",                             "login/",                             new { controller = "Customer", action = "Login" },                             new[] { "Nop.Web.Controllers" });             //register             routes.MapLocalizedRoute("Register",                             "register/",                             new { controller = "Customer", action = "Register" },                             new[] { "Nop.Web.Controllers" });             //logout             routes.MapLocalizedRoute("Logout",                             "logout/",                             new { controller = "Customer", action = "Logout" },                             new[] { "Nop.Web.Controllers" });             //shopping cart             routes.MapLocalizedRoute("ShoppingCart",                             "cart/",                             new { controller = "ShoppingCart", action = "Cart" },                             new[] { "Nop.Web.Controllers" });             //estimate shipping             routes.MapLocalizedRoute("EstimateShipping",                             "cart/estimateshipping",                             new {controller = "ShoppingCart", action = "GetEstimateShipping"},                             new[] {"Nop.Web.Controllers"});             //wishlist             routes.MapLocalizedRoute("Wishlist",                             "wishlist/{customerGuid}",                             new { controller = "ShoppingCart", action = "Wishlist", customerGuid = UrlParameter.Optional },                             new[] { "Nop.Web.Controllers" });             //customer account links             routes.MapLocalizedRoute("CustomerInfo",                             "customer/info",                             new { controller = "Customer", action = "Info" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CustomerAddresses",                             "customer/addresses",                             new { controller = "Customer", action = "Addresses" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CustomerOrders",                             "order/history",                             new { controller = "Order", action = "CustomerOrders" },                             new[] { "Nop.Web.Controllers" });             //contact us             routes.MapLocalizedRoute("ContactUs",                             "contactus",                             new { controller = "Common", action = "ContactUs" },                             new[] { "Nop.Web.Controllers" });             //sitemap             routes.MapLocalizedRoute("Sitemap",                             "sitemap",                             new { controller = "Common", action = "Sitemap" },                             new[] { "Nop.Web.Controllers" });             //product search             routes.MapLocalizedRoute("ProductSearch",                             "search/",                             new { controller = "Catalog", action = "Search" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("ProductSearchAutoComplete",                             "catalog/searchtermautocomplete",                             new { controller = "Catalog", action = "SearchTermAutoComplete" },                             new[] { "Nop.Web.Controllers" });             //change currency (AJAX link)             routes.MapLocalizedRoute("ChangeCurrency",                             "changecurrency/{customercurrency}",                             new { controller = "Common", action = "SetCurrency" },                             new { customercurrency = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //change language (AJAX link)             routes.MapLocalizedRoute("ChangeLanguage",                             "changelanguage/{langid}",                             new { controller = "Common", action = "SetLanguage" },                             new { langid = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //change tax (AJAX link)             routes.MapLocalizedRoute("ChangeTaxType",                             "changetaxtype/{customertaxtype}",                             new { controller = "Common", action = "SetTaxType" },                             new { customertaxtype = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //recently viewed products             routes.MapLocalizedRoute("RecentlyViewedProducts",                             "recentlyviewedproducts/",                             new { controller = "Product", action = "RecentlyViewedProducts" },                             new[] { "Nop.Web.Controllers" });             //new products             routes.MapLocalizedRoute("NewProducts",                             "newproducts/",                             new { controller = "Product", action = "NewProducts" },                             new[] { "Nop.Web.Controllers" });             //blog             routes.MapLocalizedRoute("Blog",                             "blog",                             new { controller = "Blog", action = "List" },                             new[] { "Nop.Web.Controllers" });             //news             routes.MapLocalizedRoute("NewsArchive",                             "news",                             new { controller = "News", action = "List" },                             new[] { "Nop.Web.Controllers" });             //forum             routes.MapLocalizedRoute("Boards",                             "boards",                             new { controller = "Boards", action = "Index" },                             new[] { "Nop.Web.Controllers" });             //compare products             routes.MapLocalizedRoute("CompareProducts",                             "compareproducts/",                             new { controller = "Product", action = "CompareProducts" },                             new[] { "Nop.Web.Controllers" });             //product tags             routes.MapLocalizedRoute("ProductTagsAll",                             "producttag/all/",                             new { controller = "Catalog", action = "ProductTagsAll" },                             new[] { "Nop.Web.Controllers" });             //manufacturers             routes.MapLocalizedRoute("ManufacturerList",                             "manufacturer/all/",                             new { controller = "Catalog", action = "ManufacturerAll" },                             new[] { "Nop.Web.Controllers" });             //vendors             routes.MapLocalizedRoute("VendorList",                             "vendor/all/",                             new { controller = "Catalog", action = "VendorAll" },                             new[] { "Nop.Web.Controllers" });             //add product to cart (without any attributes and options). used on catalog pages.             routes.MapLocalizedRoute("AddProductToCart-Catalog",                             "addproducttocart/catalog/{productId}/{shoppingCartTypeId}/{quantity}",                             new { controller = "ShoppingCart", action = "AddProductToCart_Catalog" },                             new { productId = @"\d+", shoppingCartTypeId = @"\d+", quantity = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //add product to cart (with attributes and options). used on the product details pages.             routes.MapLocalizedRoute("AddProductToCart-Details",                             "addproducttocart/details/{productId}/{shoppingCartTypeId}",                             new { controller = "ShoppingCart", action = "AddProductToCart_Details" },                             new { productId = @"\d+", shoppingCartTypeId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //product tags             routes.MapLocalizedRoute("ProductsByTag",                             "producttag/{productTagId}/{SeName}",                             new { controller = "Catalog", action = "ProductsByTag", SeName = UrlParameter.Optional },                             new { productTagId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //comparing products             routes.MapLocalizedRoute("AddProductToCompare",                             "compareproducts/add/{productId}",                             new { controller = "Product", action = "AddProductToCompareList" },                             new { productId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //product email a friend             routes.MapLocalizedRoute("ProductEmailAFriend",                             "productemailafriend/{productId}",                             new { controller = "Product", action = "ProductEmailAFriend" },                             new { productId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //reviews             routes.MapLocalizedRoute("ProductReviews",                             "productreviews/{productId}",                             new { controller = "Product", action = "ProductReviews" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CustomerProductReviews",                             "customer/productreviews",                             new { controller = "Product", action = "CustomerProductReviews" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CustomerProductReviewsPaged",                             "customer/productreviews/page/{page}",                             new { controller = "Product", action = "CustomerProductReviews" },                             new { page = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //back in stock notifications             routes.MapLocalizedRoute("BackInStockSubscribePopup",                             "backinstocksubscribe/{productId}",                             new { controller = "BackInStockSubscription", action = "SubscribePopup" },                             new { productId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("BackInStockSubscribeSend",                             "backinstocksubscribesend/{productId}",                             new { controller = "BackInStockSubscription", action = "SubscribePopupPOST" },                             new { productId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //downloads             routes.MapRoute("GetSampleDownload",                             "download/sample/{productid}",                             new { controller = "Download", action = "Sample" },                             new { productid = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //checkout pages             routes.MapLocalizedRoute("Checkout",                             "checkout/",                             new { controller = "Checkout", action = "Index" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CheckoutOnePage",                             "onepagecheckout/",                             new { controller = "Checkout", action = "OnePageCheckout" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CheckoutShippingAddress",                             "checkout/shippingaddress",                             new { controller = "Checkout", action = "ShippingAddress" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CheckoutSelectShippingAddress",                             "checkout/selectshippingaddress",                             new { controller = "Checkout", action = "SelectShippingAddress" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CheckoutBillingAddress",                             "checkout/billingaddress",                             new { controller = "Checkout", action = "BillingAddress" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CheckoutSelectBillingAddress",                             "checkout/selectbillingaddress",                             new { controller = "Checkout", action = "SelectBillingAddress" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CheckoutShippingMethod",                             "checkout/shippingmethod",                             new { controller = "Checkout", action = "ShippingMethod" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CheckoutPaymentMethod",                             "checkout/paymentmethod",                             new { controller = "Checkout", action = "PaymentMethod" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CheckoutPaymentInfo",                             "checkout/paymentinfo",                             new { controller = "Checkout", action = "PaymentInfo" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CheckoutConfirm",                             "checkout/confirm",                             new { controller = "Checkout", action = "Confirm" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CheckoutCompleted",                             "checkout/completed/{orderId}",                             new { controller = "Checkout", action = "Completed", orderId = UrlParameter.Optional },                             new { orderId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //subscribe newsletters             routes.MapLocalizedRoute("SubscribeNewsletter",                             "subscribenewsletter",                             new { controller = "Newsletter", action = "SubscribeNewsletter" },                             new[] { "Nop.Web.Controllers" });             //email wishlist             routes.MapLocalizedRoute("EmailWishlist",                             "emailwishlist",                             new { controller = "ShoppingCart", action = "EmailWishlist" },                             new[] { "Nop.Web.Controllers" });             //login page for checkout as guest             routes.MapLocalizedRoute("LoginCheckoutAsGuest",                             "login/checkoutasguest",                             new { controller = "Customer", action = "Login", checkoutAsGuest = true },                             new[] { "Nop.Web.Controllers" });             //register result page             routes.MapLocalizedRoute("RegisterResult",                             "registerresult/{resultId}",                             new { controller = "Customer", action = "RegisterResult" },                             new { resultId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //check username availability             routes.MapLocalizedRoute("CheckUsernameAvailability",                             "customer/checkusernameavailability",                             new { controller = "Customer", action = "CheckUsernameAvailability" },                             new[] { "Nop.Web.Controllers" });             //passwordrecovery             routes.MapLocalizedRoute("PasswordRecovery",                             "passwordrecovery",                             new { controller = "Customer", action = "PasswordRecovery" },                             new[] { "Nop.Web.Controllers" });             //password recovery confirmation             routes.MapLocalizedRoute("PasswordRecoveryConfirm",                             "passwordrecovery/confirm",                             new { controller = "Customer", action = "PasswordRecoveryConfirm" },                             new[] { "Nop.Web.Controllers" });             //topics             routes.MapLocalizedRoute("TopicPopup",                             "t-popup/{SystemName}",                             new { controller = "Topic", action = "TopicDetailsPopup" },                             new[] { "Nop.Web.Controllers" });             //blog             routes.MapLocalizedRoute("BlogByTag",                             "blog/tag/{tag}",                             new { controller = "Blog", action = "BlogByTag" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("BlogByMonth",                             "blog/month/{month}",                             new { controller = "Blog", action = "BlogByMonth" },                             new[] { "Nop.Web.Controllers" });             //blog RSS             routes.MapLocalizedRoute("BlogRSS",                             "blog/rss/{languageId}",                             new { controller = "Blog", action = "ListRss" },                             new { languageId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //news RSS             routes.MapLocalizedRoute("NewsRSS",                             "news/rss/{languageId}",                             new { controller = "News", action = "ListRss" },                             new { languageId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //set review helpfulness (AJAX link)             routes.MapRoute("SetProductReviewHelpfulness",                             "setproductreviewhelpfulness",                             new { controller = "Product", action = "SetProductReviewHelpfulness" },                             new[] { "Nop.Web.Controllers" });             //customer account links             routes.MapLocalizedRoute("CustomerReturnRequests",                             "returnrequest/history",                             new { controller = "ReturnRequest", action = "CustomerReturnRequests" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CustomerDownloadableProducts",                             "customer/downloadableproducts",                             new { controller = "Customer", action = "DownloadableProducts" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CustomerBackInStockSubscriptions",                             "backinstocksubscriptions/manage",                             new { controller = "BackInStockSubscription", action = "CustomerSubscriptions" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CustomerBackInStockSubscriptionsPaged",                             "backinstocksubscriptions/manage/{page}",                             new { controller = "BackInStockSubscription", action = "CustomerSubscriptions", page = UrlParameter.Optional },                             new { page = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CustomerRewardPoints",                             "rewardpoints/history",                             new { controller = "Order", action = "CustomerRewardPoints" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CustomerRewardPointsPaged",                             "rewardpoints/history/page/{page}",                             new { controller = "Order", action = "CustomerRewardPoints" },                             new { page = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CustomerChangePassword",                             "customer/changepassword",                             new { controller = "Customer", action = "ChangePassword" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CustomerAvatar",                             "customer/avatar",                             new { controller = "Customer", action = "Avatar" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("AccountActivation",                             "customer/activation",                             new { controller = "Customer", action = "AccountActivation" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("EmailRevalidation",                             "customer/revalidateemail",                             new { controller = "Customer", action = "EmailRevalidation" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CustomerForumSubscriptions",                             "boards/forumsubscriptions",                             new { controller = "Boards", action = "CustomerForumSubscriptions" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CustomerForumSubscriptionsPaged",                             "boards/forumsubscriptions/{page}",                             new { controller = "Boards", action = "CustomerForumSubscriptions", page = UrlParameter.Optional },                             new { page = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CustomerAddressEdit",                             "customer/addressedit/{addressId}",                             new { controller = "Customer", action = "AddressEdit" },                             new { addressId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CustomerAddressAdd",                             "customer/addressadd",                             new { controller = "Customer", action = "AddressAdd" },                             new[] { "Nop.Web.Controllers" });             //customer profile page             routes.MapLocalizedRoute("CustomerProfile",                             "profile/{id}",                             new { controller = "Profile", action = "Index" },                             new { id = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("CustomerProfilePaged",                             "profile/{id}/page/{page}",                             new { controller = "Profile", action = "Index" },                             new { id = @"\d+", page = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //orders             routes.MapLocalizedRoute("OrderDetails",                             "orderdetails/{orderId}",                             new { controller = "Order", action = "Details" },                             new { orderId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("ShipmentDetails",                             "orderdetails/shipment/{shipmentId}",                             new { controller = "Order", action = "ShipmentDetails" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("ReturnRequest",                             "returnrequest/{orderId}",                             new { controller = "ReturnRequest", action = "ReturnRequest" },                             new { orderId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("ReOrder",                             "reorder/{orderId}",                             new { controller = "Order", action = "ReOrder" },                             new { orderId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("GetOrderPdfInvoice",                             "orderdetails/pdf/{orderId}",                             new { controller = "Order", action = "GetPdfInvoice" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("PrintOrderDetails",                             "orderdetails/print/{orderId}",                             new { controller = "Order", action = "PrintOrderDetails" },                             new[] { "Nop.Web.Controllers" });             //order downloads             routes.MapRoute("GetDownload",                             "download/getdownload/{orderItemId}/{agree}",                             new { controller = "Download", action = "GetDownload", agree = UrlParameter.Optional },                             new { orderItemId = new GuidConstraint(false) },                             new[] { "Nop.Web.Controllers" });             routes.MapRoute("GetLicense",                             "download/getlicense/{orderItemId}/",                             new { controller = "Download", action = "GetLicense" },                             new { orderItemId = new GuidConstraint(false) },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("DownloadUserAgreement",                             "customer/useragreement/{orderItemId}",                             new { controller = "Customer", action = "UserAgreement" },                             new { orderItemId = new GuidConstraint(false) },                             new[] { "Nop.Web.Controllers" });             routes.MapRoute("GetOrderNoteFile",                             "download/ordernotefile/{ordernoteid}",                             new { controller = "Download", action = "GetOrderNoteFile" },                             new { ordernoteid = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //contact vendor             routes.MapLocalizedRoute("ContactVendor",                             "contactvendor/{vendorId}",                             new { controller = "Common", action = "ContactVendor" },                             new[] { "Nop.Web.Controllers" });             //apply for vendor account             routes.MapLocalizedRoute("ApplyVendorAccount",                             "vendor/apply",                             new { controller = "Vendor", action = "ApplyVendor" },                             new[] { "Nop.Web.Controllers" });             //vendor info             routes.MapLocalizedRoute("CustomerVendorInfo",                             "customer/vendorinfo",                             new { controller = "Vendor", action = "Info" },                             new[] { "Nop.Web.Controllers" });             //poll vote AJAX link             routes.MapLocalizedRoute("PollVote",                             "poll/vote",                             new { controller = "Poll", action = "Vote" },                             new[] { "Nop.Web.Controllers" });             //comparing products             routes.MapLocalizedRoute("RemoveProductFromCompareList",                             "compareproducts/remove/{productId}",                             new { controller = "Product", action = "RemoveProductFromCompareList" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("ClearCompareList",                             "clearcomparelist/",                             new { controller = "Product", action = "ClearCompareList" },                             new[] { "Nop.Web.Controllers" });             //new RSS             routes.MapLocalizedRoute("NewProductsRSS",                             "newproducts/rss",                             new { controller = "Product", action = "NewProductsRss" },                             new[] { "Nop.Web.Controllers" });             //get state list by country ID  (AJAX link)             routes.MapRoute("GetStatesByCountryId",                             "country/getstatesbycountryid/",                             new { controller = "Country", action = "GetStatesByCountryId" },                             new[] { "Nop.Web.Controllers" });             //EU Cookie law accept button handler (AJAX link)             routes.MapRoute("EuCookieLawAccept",                             "eucookielawaccept",                             new { controller = "Common", action = "EuCookieLawAccept" },                             new[] { "Nop.Web.Controllers" });             //authenticate topic AJAX link             routes.MapLocalizedRoute("TopicAuthenticate",                             "topic/authenticate",                             new { controller = "Topic", action = "Authenticate" },                             new[] { "Nop.Web.Controllers" });             //product attributes with "upload file" type             routes.MapLocalizedRoute("UploadFileProductAttribute",                             "uploadfileproductattribute/{attributeId}",                             new { controller = "ShoppingCart", action = "UploadFileProductAttribute" },                             new { attributeId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //checkout attributes with "upload file" type             routes.MapLocalizedRoute("UploadFileCheckoutAttribute",                             "uploadfilecheckoutattribute/{attributeId}",                             new { controller = "ShoppingCart", action = "UploadFileCheckoutAttribute" },                             new { attributeId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //return request with "upload file" tsupport             routes.MapLocalizedRoute("UploadFileReturnRequest",                             "uploadfilereturnrequest",                             new { controller = "ReturnRequest", action = "UploadFileReturnRequest" },                             new[] { "Nop.Web.Controllers" });             //forums             routes.MapLocalizedRoute("ActiveDiscussions",                             "boards/activediscussions",                             new { controller = "Boards", action = "ActiveDiscussions" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("ActiveDiscussionsPaged",                             "boards/activediscussions/page/{page}",                             new { controller = "Boards", action = "ActiveDiscussions", page = UrlParameter.Optional },                             new { page = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("ActiveDiscussionsRSS",                             "boards/activediscussionsrss",                             new { controller = "Boards", action = "ActiveDiscussionsRSS" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("PostEdit",                             "boards/postedit/{id}",                             new { controller = "Boards", action = "PostEdit" },                             new { id = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("PostDelete",                             "boards/postdelete/{id}",                             new { controller = "Boards", action = "PostDelete" },                             new { id = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("PostCreate",                             "boards/postcreate/{id}",                             new { controller = "Boards", action = "PostCreate" },                             new { id = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("PostCreateQuote",                             "boards/postcreate/{id}/{quote}",                             new { controller = "Boards", action = "PostCreate" },                             new { id = @"\d+", quote = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("TopicEdit",                             "boards/topicedit/{id}",                             new { controller = "Boards", action = "TopicEdit" },                             new { id = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("TopicDelete",                             "boards/topicdelete/{id}",                             new { controller = "Boards", action = "TopicDelete" },                             new { id = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("TopicCreate",                             "boards/topiccreate/{id}",                             new { controller = "Boards", action = "TopicCreate" },                             new { id = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("TopicMove",                             "boards/topicmove/{id}",                             new { controller = "Boards", action = "TopicMove" },                             new { id = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("TopicWatch",                             "boards/topicwatch/{id}",                             new { controller = "Boards", action = "TopicWatch" },                             new { id = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("TopicSlug",                             "boards/topic/{id}/{slug}",                             new { controller = "Boards", action = "Topic", slug = UrlParameter.Optional },                             new { id = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("TopicSlugPaged",                             "boards/topic/{id}/{slug}/page/{page}",                             new { controller = "Boards", action = "Topic", slug = UrlParameter.Optional, page = UrlParameter.Optional },                             new { id = @"\d+", page = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("ForumWatch",                             "boards/forumwatch/{id}",                             new { controller = "Boards", action = "ForumWatch" },                             new { id = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("ForumRSS",                             "boards/forumrss/{id}",                             new { controller = "Boards", action = "ForumRSS" },                             new { id = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("ForumSlug",                             "boards/forum/{id}/{slug}",                             new { controller = "Boards", action = "Forum", slug = UrlParameter.Optional },                             new { id = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("ForumSlugPaged",                             "boards/forum/{id}/{slug}/page/{page}",                             new { controller = "Boards", action = "Forum", slug = UrlParameter.Optional, page = UrlParameter.Optional },                             new { id = @"\d+", page = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("ForumGroupSlug",                             "boards/forumgroup/{id}/{slug}",                             new { controller = "Boards", action = "ForumGroup", slug = UrlParameter.Optional },                             new { id = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("Search",                             "boards/search",                             new { controller = "Boards", action = "Search" },                             new[] { "Nop.Web.Controllers" });             //private messages             routes.MapLocalizedRoute("PrivateMessages",                             "privatemessages/{tab}",                             new { controller = "PrivateMessages", action = "Index", tab = UrlParameter.Optional },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("PrivateMessagesPaged",                             "privatemessages/{tab}/page/{page}",                             new { controller = "PrivateMessages", action = "Index", tab = UrlParameter.Optional },                             new { page = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("PrivateMessagesInbox",                             "inboxupdate",                             new { controller = "PrivateMessages", action = "InboxUpdate" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("PrivateMessagesSent",                             "sentupdate",                             new { controller = "PrivateMessages", action = "SentUpdate" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("SendPM",                             "sendpm/{toCustomerId}",                             new { controller = "PrivateMessages", action = "SendPM" },                             new { toCustomerId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("SendPMReply",                             "sendpm/{toCustomerId}/{replyToMessageId}",                             new { controller = "PrivateMessages", action = "SendPM" },                             new { toCustomerId = @"\d+", replyToMessageId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("ViewPM",                             "viewpm/{privateMessageId}",                             new { controller = "PrivateMessages", action = "ViewPM" },                             new { privateMessageId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("DeletePM",                             "deletepm/{privateMessageId}",                             new { controller = "PrivateMessages", action = "DeletePM" },                             new { privateMessageId = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //activate newsletters             routes.MapLocalizedRoute("NewsletterActivation",                             "newsletter/subscriptionactivation/{token}/{active}",                             new { controller = "Newsletter", action = "SubscriptionActivation" },                             new { token = new GuidConstraint(false) },                             new[] { "Nop.Web.Controllers" });             //robots.txt             routes.MapRoute("robots.txt",                             "robots.txt",                             new { controller = "Common", action = "RobotsTextFile" },                             new[] { "Nop.Web.Controllers" });             //sitemap (XML)             routes.MapLocalizedRoute("sitemap.xml",                             "sitemap.xml",                             new { controller = "Common", action = "SitemapXml" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("sitemap-indexed.xml",                             "sitemap-{Id}.xml",                             new { controller = "Common", action = "SitemapXml" },                             new { Id = @"\d+" },                             new[] { "Nop.Web.Controllers" });             //store closed             routes.MapLocalizedRoute("StoreClosed",                             "storeclosed",                             new { controller = "Common", action = "StoreClosed" },                             new[] { "Nop.Web.Controllers" });             //install             routes.MapRoute("Installation",                             "install",                             new { controller = "Install", action = "Index" },                             new[] { "Nop.Web.Controllers" });             //page not found             routes.MapLocalizedRoute("PageNotFound",                             "page-not-found",                             new { controller = "Common", action = "PageNotFound" },                             new[] { "Nop.Web.Controllers" });         }         public int Priority         {             get             {                 return 0;             }         }     } }

Nop.Web.Infrastructure.RouteProvider

Nop.Web.Framework.Localization.LocalizedRouteExtensions类中对RouteCollection routes添加了MapLocalizedRoute的扩展方法

    routes.MapLocalizedRoute("HomePage",                             "",                             new { controller = "Home", action = "Index" },                             new[] { "Nop.Web.Controllers" });

Nop.Web.Framework.Localization.LocalizedRoute继承Route类进行扩展多语言Seo的支持

    public static Route MapLocalizedRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces)         {             if (routes == null)             {                 throw new ArgumentNullException("routes");             }             if (url == null)             {                 throw new ArgumentNullException("url");             }             //LocalizedRoute 进行了多语言Seo优化
             var route = new LocalizedRoute(url, new MvcRouteHandler())             {                 Defaults = new RouteValueDictionary(defaults),                 Constraints = new RouteValueDictionary(constraints),                 DataTokens = new RouteValueDictionary()             };             if ((namespaces != null) && (namespaces.Length > 0))             {                 route.DataTokens["Namespaces"] = namespaces;             }             routes.Add(name, route);             return route;         }

LocalizedRoute对路由进行了扩展,主要重写了GetRouteData,和GetVirtualPath这两个方法。

GetRouteData:解析Url,它的作用简单理解是通过url匹配到正确的路由。

开启多语言Seo后URL格式为: http://www.yourStore.com/en/ 或 http://www.yourStore.com/zh/ (SEO比较友好),

LocalizedRoute重写GetRouteData方法,会去掉en或zh后,匹配正确的路由位置。

例如输入http://localhost:15536/en,会正确的匹配到http://localhost:15536/

    routes.MapLocalizedRoute("HomePage",                             "",                             new { controller = "Home", action = "Index" },                             new[] { "Nop.Web.Controllers" });

GetVirtualPath:生成Url,我们在Razor视图中常会看到<a href=”@Url.Action(“Index”, “Home”)”>首页</a>这种标签,

GetVirtualPath负责将”@Url.Action(“Index”, “Home”)”生成支持多语言Seo的url字符串http://www.yourStore.com/en/ ,自动会加上en或zh。

更好的理解GetRouteData和GetVirtualPath,可自行搜索下。

搜索引擎友好名称实现

除了对多语言Seo友好链接支持,nop还支持Seo友好链接的支持。

我们发现Nop.Web.Infrastructure.GenericUrlRouteProvider类主要用于Seo友好链接的路由注册,代码如下:

 using System.Web.Routing; using Nop.Web.Framework.Localization; using Nop.Web.Framework.Mvc.Routes; using Nop.Web.Framework.Seo; namespace Nop.Web.Infrastructure {     public partial class GenericUrlRouteProvider : IRouteProvider     {         public void RegisterRoutes(RouteCollection routes)         {             //generic URLs             routes.MapGenericPathRoute("GenericUrl",                                        "{generic_se_name}",                                        new {controller = "Common", action = "GenericUrl"},                                        new[] {"Nop.Web.Controllers"});             //define this routes to use in UI views (in case if you want to customize some of them later)             routes.MapLocalizedRoute("Product",                                      "{SeName}",                                      new { controller = "Product", action = "ProductDetails" },                                      new[] {"Nop.Web.Controllers"});             routes.MapLocalizedRoute("Category",                             "{SeName}",                             new { controller = "Catalog", action = "Category" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("Manufacturer",                             "{SeName}",                             new { controller = "Catalog", action = "Manufacturer" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("Vendor",                             "{SeName}",                             new { controller = "Catalog", action = "Vendor" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("NewsItem",                             "{SeName}",                             new { controller = "News", action = "NewsItem" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("BlogPost",                             "{SeName}",                             new { controller = "Blog", action = "BlogPost" },                             new[] { "Nop.Web.Controllers" });             routes.MapLocalizedRoute("Topic",                             "{SeName}",                             new { controller = "Topic", action = "TopicDetails" },                             new[] { "Nop.Web.Controllers" });             //the last route. it's used when none of registered routes could be used for the current request             //but in this case we cannot process non-registered routes (/controller/action)             //routes.MapLocalizedRoute(             //    "PageNotFound-Wildchar",             //    "{*url}",             //    new { controller = "Common", action = "PageNotFound" },             //    new[] { "Nop.Web.Controllers" });         }         public int Priority         {             get             {                 //it should be the last route                 //we do not set it to -int.MaxValue so it could be overridden (if required)                 return -1000000;             }         }     } } 

Nop.Web.Infrastructure.GenericUrlRouteProvider

我们发现多了MapGenericPathRoute的扩展

   //generic URLs             routes.MapGenericPathRoute("GenericUrl",                                        "{generic_se_name}",                                        new {controller = "Common", action = "GenericUrl"},                                        new[] {"Nop.Web.Controllers"});

我们来看看MapGenericPathRoute方法来自Nop.Web.Framework.Seo.GenericPathRouteExtensions类中。

通过Nop.Web.Framework.Seo.GenericPathRoute完成Seo友好链接的路由扩展

   public static Route MapGenericPathRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces)         {             if (routes == null)             {                 throw new ArgumentNullException("routes");             }             if (url == null)             {                 throw new ArgumentNullException("url");             }             //GenericPathRoute中实现Seo友好链接路由             var route = new GenericPathRoute(url, new MvcRouteHandler())             {                 Defaults = new RouteValueDictionary(defaults),                 Constraints = new RouteValueDictionary(constraints),                 DataTokens = new RouteValueDictionary()             };             if ((namespaces != null) && (namespaces.Length > 0))             {                 route.DataTokens["Namespaces"] = namespaces;             }             routes.Add(name, route);             return route;         }

GenericPathRoute对路由进行扩展,只重写了GetRouteData方法用于解析url,帮助路由到正确的执行位置。代码如下:

 /// <summary>         /// Returns information about the requested route.         /// </summary>         /// <param name="httpContext">An object that encapsulates information about the HTTP request.</param>         /// <returns>         /// An object that contains the values from the route definition.         /// </returns>         public override RouteData GetRouteData(HttpContextBase httpContext)         {             RouteData data = base.GetRouteData(httpContext); return null;             if (data != null && DataSettingsHelper.DatabaseIsInstalled())             {                 var urlRecordService = EngineContext.Current.Resolve<IUrlRecordService>();                 var slug = data.Values["generic_se_name"] as string;                 //performance optimization.                 //we load a cached verion here. it reduces number of SQL requests for each page load                 var urlRecord = urlRecordService.GetBySlugCached(slug);                 //comment the line above and uncomment the line below in order to disable this performance "workaround"                 //var urlRecord = urlRecordService.GetBySlug(slug);                 if (urlRecord == null)                 {                     //no URL record found                     //var webHelper = EngineContext.Current.Resolve<IWebHelper>();                     //var response = httpContext.Response;                     //response.Status = "302 Found";                     //response.RedirectLocation = webHelper.GetStoreLocation(false);                     //response.End();                     //return null;                     data.Values["controller"] = "Common";                     data.Values["action"] = "PageNotFound";                     return data;                 }                 //ensure that URL record is active                 if (!urlRecord.IsActive)                 {                     //URL record is not active. let's find the latest one                     var activeSlug = urlRecordService.GetActiveSlug(urlRecord.EntityId, urlRecord.EntityName, urlRecord.LanguageId);                     if (string.IsNullOrWhiteSpace(activeSlug))                     {                         //no active slug found                         //var webHelper = EngineContext.Current.Resolve<IWebHelper>();                         //var response = httpContext.Response;                         //response.Status = "302 Found";                         //response.RedirectLocation = webHelper.GetStoreLocation(false);                         //response.End();                         //return null;                         data.Values["controller"] = "Common";                         data.Values["action"] = "PageNotFound";                         return data;                     }                     //the active one is found                     var webHelper = EngineContext.Current.Resolve<IWebHelper>();                     var response = httpContext.Response;                     response.Status = "301 Moved Permanently";                     response.RedirectLocation = string.Format("{0}{1}", webHelper.GetStoreLocation(), activeSlug);                     response.End();                     return null;                 }                 //ensure that the slug is the same for the current language                 //otherwise, it can cause some issues when customers choose a new language but a slug stays the same                 var workContext = EngineContext.Current.Resolve<IWorkContext>();                 var slugForCurrentLanguage = SeoExtensions.GetSeName(urlRecord.EntityId, urlRecord.EntityName, workContext.WorkingLanguage.Id);                 if (!String.IsNullOrEmpty(slugForCurrentLanguage) &&                     !slugForCurrentLanguage.Equals(slug, StringComparison.InvariantCultureIgnoreCase))                 {                     //we should make not null or "" validation above because some entities does not have SeName for standard (ID=0) language (e.g. news, blog posts)                     var webHelper = EngineContext.Current.Resolve<IWebHelper>();                     var response = httpContext.Response;                     //response.Status = "302 Found";                     response.Status = "302 Moved Temporarily";                     response.RedirectLocation = string.Format("{0}{1}", webHelper.GetStoreLocation(), slugForCurrentLanguage);                     response.End();                     return null;                 }                 //process URL                 switch (urlRecord.EntityName.ToLowerInvariant())                 {                     case "product":                         {                             data.Values["controller"] = "Product";                             data.Values["action"] = "ProductDetails";                             data.Values["productid"] = urlRecord.EntityId;                             data.Values["SeName"] = urlRecord.Slug;                         }                         break;                     case "category":                         {                             data.Values["controller"] = "Catalog";                             data.Values["action"] = "Category";                             data.Values["categoryid"] = urlRecord.EntityId;                             data.Values["SeName"] = urlRecord.Slug;                         }                         break;                     case "manufacturer":                         {                             data.Values["controller"] = "Catalog";                             data.Values["action"] = "Manufacturer";                             data.Values["manufacturerid"] = urlRecord.EntityId;                             data.Values["SeName"] = urlRecord.Slug;                         }                         break;                     case "vendor":                         {                             data.Values["controller"] = "Catalog";                             data.Values["action"] = "Vendor";                             data.Values["vendorid"] = urlRecord.EntityId;                             data.Values["SeName"] = urlRecord.Slug;                         }                         break;                     case "newsitem":                         {                             data.Values["controller"] = "News";                             data.Values["action"] = "NewsItem";                             data.Values["newsItemId"] = urlRecord.EntityId;                             data.Values["SeName"] = urlRecord.Slug;                         }                         break;                     case "blogpost":                         {                             data.Values["controller"] = "Blog";                             data.Values["action"] = "BlogPost";                             data.Values["blogPostId"] = urlRecord.EntityId;                             data.Values["SeName"] = urlRecord.Slug;                         }                         break;                     case "topic":                         {                             data.Values["controller"] = "Topic";                             data.Values["action"] = "TopicDetails";                             data.Values["topicId"] = urlRecord.EntityId;                             data.Values["SeName"] = urlRecord.Slug;                         }                         break;                     default:                         {                             //no record found                             //generate an event this way developers could insert their own types                             EngineContext.Current.Resolve<IEventPublisher>()                                 .Publish(new CustomUrlRecordEntityNameRequested(data, urlRecord));                         }                         break;                 }             }             return data;         }

GetRouteData

路由匹配到支持Seo友好链接会重定向链接新的路由位置,nop 3.9目前支持下图中的路由

提示:数据库UrlRecord表对Seo友情链接提供支持。

总结

1.继承IRouteProvider对路由进行扩展。(注意路由注册顺序,ASP.NET MVC 只匹配第一次成功的路由信息)

2.多语言Seo友好链接通过LocalizedRoute类进行路由扩展(MapLocalizedRoute扩展中调用)

3.页面Seo友好链接通过GenericPathRoute类进行路由扩展(MapGenericPathRoute扩展中调用)

文中有错误的理解和不正确的观点,请留言,一起交流共同进步。

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,997
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,511
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,356
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,139
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,770
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,848