【问题标题】:Alter generated URLs in MVC globally全局更改 MVC 中生成的 URL
【发布时间】:2013-04-27 01:00:13
【问题描述】:

我有一个非常简单的问题。

我只是希望能够更改由 MVC.NET 中的帮助程序类创建的每个 URL,问题是我不知道我必须重写什么。

编辑:我的目标是在创建 url 时改变 MVC 的行为。我想让 MVC 创建的 url 对 seo 友好。

在使用 Google 和 Bing 几个小时后,我并没有变得更聪明...

如果有人知道我要改什么地方,请给我提示,谢谢:)

【问题讨论】:

    标签: c# asp.net-mvc url routing seo


    【解决方案1】:

    掌握路由:

    http://www.asp.net/mvc/tutorials/older-versions/controllers-and-routing/asp-net-mvc-routing-overview-cs

    路由可以在 Global.asax 文件中找到,像 ActionLink 这样的 HtmlHelpers 应该会自动适应您的自定义路由。如果您在默认路由之上指定自定义路由,然后执行以下操作,则生成的 URL 将匹配该路由:

    @Html.ActionLink("Go!", "AnAction", "AController")
    

    如果您在路由中指定了其他参数,这些参数不能作为ActionLink 标准重载的参数,您可以在routeValues 参数中传递这些参数:

    @Html.ActionLink("Go!", "AnAction", "AController",
        new { MyCustomParameter = "Hello" })
    

    【讨论】:

    • 嗨,谢谢...我知道路线是如何运作的。我的目标是将创建的 url 更改为 SEO 友好的 url...我不想在我生成的任何 url 中都这样做,所以我正在寻找一种方法来改变 MVC 从路由创建 url 的行为。跨度>
    • 好吧,你的路由就是你的 URL,所以没有真正的方法可以通过路由来实现这一点。您没有指定任何示例,但假设您有一个通用模式,处理此问题的正确方法是 URL 重写:iis.net/learn/extensions/url-rewrite-module/…
    • 据我了解,MVC 将遍历您的 routecollection,直到它可以匹配具有给定参数的路由。然后它将为找到的路由创建一个 url。在这里我想改变系统的行为。
    • 无论如何,IIS url 重写的解决方案可能会满足我们的需求,谢谢。
    • 在这种情况下,您可能希望查看以下内容:stackoverflow.com/a/495332/1043198
    【解决方案2】:
    using System;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;
    
    namespace yourbelovedNamespace
    {
        /// <summary>
        /// Provides properties and methods for defining a seo friendly route
        /// </summary>
        public class SeoFriendlyRoute : Route
        {
            #region Constructors
    
            public SeoFriendlyRoute(string url, IRouteHandler routeHandler)
                : base(url, routeHandler)
            {
            }
    
            public SeoFriendlyRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler)
                : base(url, defaults, routeHandler)
            {
            }
    
            public SeoFriendlyRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints,
                                    IRouteHandler routeHandler)
                : base(url, defaults, constraints, routeHandler)
            {
            }
    
            public SeoFriendlyRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints,
                                    RouteValueDictionary dataTokens, IRouteHandler routeHandler)
                : base(url, defaults, constraints, dataTokens, routeHandler)
            {
            }
    
            #endregion
    
            public override RouteData GetRouteData(HttpContextBase httpContext)
            {
                RouteData data = base.GetRouteData(httpContext);
                return data;
            }
    
            public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
            {
                var trimmedValues = new RouteValueDictionary();
                foreach (var value in values)
                {
                    if (value.Value != null && value.Key != "controller" && value.Key != "action")
                        trimmedValues.Add(value.Key, GenerateSeourl(value.Value.ToString()));
                    else
                    {
                        trimmedValues.Add(value.Key, value.Value != null ? value.Value.ToString() : value.Value);
                    }
    
                }
                VirtualPathData data = base.GetVirtualPath(requestContext, trimmedValues);
                if (data != null)
                    data.VirtualPath = data.VirtualPath;
                return data;
            }
    
            private static string GenerateSeourl(string url)
            {
                // make the url lowercase
                var encodedUrl = (url ?? "");
                encodedUrl = encodedUrl
                    .Replace("%20", "")
                    .Replace(" ", "")
                    .Replace("/", "-");
                return encodedUrl;
            }
        }
    
        public static class SeoFriendlyRouteCollectionExtensions
        {
            //Override for localized route
            public static Route MapSeoFriendlyRoute(this RouteCollection routes, string name, string url, object defaults)
            {
                return routes.MapSeoFriendlyRoute(name, url, defaults, null, null);
            }
    
            public static Route MapSeoFriendlyRoute(this RouteCollection routes, string name, string url, object defaults,
                                                    object constraints)
            {
                return routes.MapSeoFriendlyRoute(name, url, defaults, constraints, null);
            }
    
            public static Route MapSeoFriendlyRoute(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");
                }
                var item = new SeoFriendlyRoute(url, new MvcRouteHandler())
                               {
                                   Defaults = new RouteValueDictionary(defaults),
                                   Constraints = new RouteValueDictionary(constraints),
                                   DataTokens = new RouteValueDictionary()
                               };
                if ((namespaces != null) && (namespaces.Length > 0))
                {
                    item.DataTokens["Namespaces"] = namespaces;
                }
                routes.Add(name, item);
                return item;
                //return routes.MapSeoFriendlyRoute(name, urlPattern, defaults, null);
            }
    
            private static Route MapSeoFriendlyRoute(this AreaRegistrationContext context, string name, string url,
                                                     object defaults, object constraints, string[] namespaces)
            {
                if ((namespaces == null) && (context.Namespaces != null))
                {
                    namespaces = context.Namespaces.ToArray();
                }
    
                Route route = context.Routes.MapSeoFriendlyRoute(name, url, defaults, constraints, namespaces);
                route.DataTokens["area"] = context.AreaName;
                bool flag = (namespaces == null) || (namespaces.Length == 0);
                route.DataTokens["UseNamespaceFallback"] = flag;
                return route;
            }
    
            public static Route MapSeoFriendlyRoute(this AreaRegistrationContext context, string name, string url,
                                                    object defaults, string[] namespaces)
            {
                return context.MapSeoFriendlyRoute(name, url, defaults, null, namespaces);
            }
    
            public static Route MapSeoFriendlyRoute(this AreaRegistrationContext context, string name, string url,
                                                    object defaults, object constraints)
            {
                return context.MapSeoFriendlyRoute(name, url, defaults, constraints, null);
            }
    
            public static Route MapSeoFriendlyRoute(this AreaRegistrationContext context, string name, string url,
                                                    string[] namespaces)
            {
                return context.MapSeoFriendlyRoute(name, url, null, namespaces);
            }
    
            public static Route MapSeoFriendlyRoute(this AreaRegistrationContext context, string name, string url,
                                                    object defaults)
            {
                return context.MapSeoFriendlyRoute(name, url, defaults, null);
            }
    
            public static Route MapSeoFriendlyRoute(this AreaRegistrationContext context, string name, string url)
            {
                return context.MapSeoFriendlyRoute(name, url, null);
            }
        }
    }
    

    所以这是我解决问题的方法。它允许在区域和默认的 RouteConfig 中注册“SEO”路线。

    修剪过程不是很成熟,只是为了演示目的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-20
      • 2017-03-18
      • 1970-01-01
      • 2012-06-05
      • 2012-06-03
      • 2015-11-09
      • 1970-01-01
      • 2010-12-10
      相关资源
      最近更新 更多