我一般如何在 MapRoute 方法中实现 URL 重写? [英] How do I generically implement URL-rewriting in a MapRoute method?
问题描述
我正在尝试将 URL 从 C# 的 Pascal-case 重写为 SEO 友好格式.
例如,我希望 /User/Home/MyJumbledPageName
看起来像这样:
/user/home/my-jumbled-page-name // lower-case, and words separated by dashes
这是我转换 URL 中每个令牌"的方法:
Here is my method for converting each "token" in the URL:
public static string GetSEOFriendlyToken(string token)
{
StringBuilder str = new StringBuilder();
for (int i = 0, len = token.Length; i < len; i++)
{
if (i == 0)
{
// setting the first capital char to lower-case:
str.Append(Char.ToLower(token[i]));
}
else if (Char.IsUpper(token[i]))
{
// setting any other capital char to lower-case, preceded by a dash:
str.Append("-" + Char.ToLower(token[i]));
}
else
{
str.Append(token[i]);
}
}
return str.ToString();
}
...在我的 RouteConfig.cs
文件中,我已经映射了这些路由:
...and in my RouteConfig.cs
file in the root, I have mapped these routes:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// without this the first URL is blank:
routes.MapRoute(
name: "Default_Home",
url: "index", // hard-coded?? it works...
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Home",
// the method calls here do not seem to have any effect:
url: GetSEOFriendlyToken("{action}") + "/" + GetSEOFriendlyToken("{id}"),
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
使用此代码,/AboutTheAuthor
之类的 URL 不会转换为我想要的,即 /about-the-author
.
似乎我的方法调用被忽略了,这里发生了什么?实现这一点的传统方法是什么?
With this code, a URL such as /AboutTheAuthor
is not converted to what I want, which would be /about-the-author
.
It seems that my method call is ignored, what's happening here? And what's the conventional way to implement this?
推荐答案
你必须定义你自己的RouteBase
类或子类Route
You have to define your own RouteBase
class or subclass Route
public class SeoFriendlyRoute : Route
{
private readonly string[] _valuesToSeo;
public SeoFriendlyRoute(string url, RouteValueDictionary defaults, IEnumerable<string> valuesToSeo, RouteValueDictionary constraints = null, RouteValueDictionary dataTokens = null, IRouteHandler routeHandler = null)
: base(url, defaults, constraints ?? new RouteValueDictionary(), dataTokens ?? new RouteValueDictionary(), routeHandler ?? new MvcRouteHandler())
{
if (valuesToSeo == null) { throw new ArgumentNullException("valuesToSeo"); }
_valuesToSeo = valuesToSeo.ToArray();
}
public override RouteData GetRouteData(HttpContextBase httpContext)
{
var routeData = base.GetRouteData(httpContext);
if (routeData != null)
{
foreach (var key in _valuesToSeo)
{
if (routeData.Values.ContainsKey(key))
{
routeData.Values[key] = GetActualValue((string)routeData.Values[key]);
}
}
}
return routeData;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
var seoFriendyValues = new RouteValueDictionary(values);
foreach (var key in _valuesToSeo)
{
if (seoFriendyValues.ContainsKey(key))
{
seoFriendyValues[key] = GetSeoFriendlyValue((string)seoFriendyValues[key]);
}
}
return base.GetVirtualPath(requestContext, seoFriendyValues);
}
private string GetSeoFriendlyValue(string actualValue)
{
//your method
StringBuilder str = new StringBuilder();
for (int i = 0, len = actualValue.Length; i < len; i++)
{
if (i == 0)
{
str.Append(Char.ToLower(actualValue[i]));
}
else if (Char.IsUpper(actualValue[i]))
{
str.Append("-" + Char.ToLower(actualValue[i]));
}
else
{
str.Append(actualValue[i]);
}
}
return str.ToString();
}
private static string GetActualValue(string seoFriendlyValue)
{
//action name is not case sensitive
//one limitation is the dash can be anywhere but the action will still be resolved
// /my-jumbled-page-name is same as /myjumbled-pagename
return seoFriendlyValue.Replace("-", string.Empty);
}
}
用法
routes.Add("Default", new SeoFriendlyRoute(
url: "{controller}/{action}/{id}",
valuesToSeo: new string[] { "action", "controller" },
defaults: new RouteValueDictionary(new { controller = "Home", action = "Index", id = UrlParameter.Optional }))
);
这篇关于我一般如何在 MapRoute 方法中实现 URL 重写?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!