如果一部分URL丢失,如何将ASP.NET MVC中的请求重定向到其正确的规范版本?
使用Stack Overflow作为示例,网站将问题标题添加到其路由的末尾,但使用问题ID在路由中实际找到问题。如果标题省略,您将被重定向到正确的URL。
例如,访问网址:
stackoverflow.com/questions/9033
将重定向到
stackoverflow.com/questions/9033/hidden-features-of-c
这个怎么用?
解决方法
首先创建一个路由:
routes.MapRoute( "ViewProduct","Products/{id}/{productName}",new { controller = "Product",action = "Details",id = "",productName = "" } );
然后创建Action方法如下:
public ActionResult Details(int? id,string productName) { Product product = ProductRepository.Fetch(id); string realTitle = UrlEncoder.ToFriendlyUrl(product.Title); string urlTitle = (productName ?? "").Trim().ToLower(); if (realTitle != urlTitle) { string url = "/Products/" + product.Id + "/" + realTitle; return new PermanentRedirectResult(url); } return View(product); }
你基本上将URL中的实体标题与存储在数据库中的实体标题进行比较,如果它们不匹配,则执行301永久重定向。确保它是一个“永久”重定向(301状态代码),而不是临时重定向(302)。这样,搜索引擎会将其视为永久更改URL,并相应地更新其索引,如果实体标题在搜索引擎编入索引后发生更改(例如某人更改了产品名称),则可能会发生这种情况。
另一件需要注意的事情,如果您的标题允许任何自由文本,您需要删除任何无效的网址的字符,并使其更可读的人类和搜索引擎,因此UrlEncoder.ToFriendlyUrl方法在代码以上,实现如下:
public static class UrlEncoder { public static string ToFriendlyUrl (this UrlHelper helper,string urlToEncode) { urlToEncode = (urlToEncode ?? "").Trim().ToLower(); StringBuilder url = new StringBuilder(); foreach (char ch in urlToEncode) { switch (ch) { case ' ': url.Append('-'); break; case '&': url.Append("and"); break; case '\'': break; default: if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z')) { url.Append(ch); } else { url.Append('-'); } break; } } return url.ToString(); } }
因此,当您将网址写入视图时,请务必使用此方法对标题进行编码。
<a href="/Products/@Model.Id/@Url.ToFriendlyUrl(Model.Title)">@Model.Title</a>
我写了一个博客文章这里http://www.dominicpettifer.co.uk/Blog/34/asp-net-mvc-and-clean-seo-friendly-urls