编辑:现在我需要真正解决这个问题,我做了一点 调查并想出了一个 减少重复的事情数量 内容。我发布了详细的代码 我博客上的示例:Reducing Duplicate Content with ASP.NET MVC
第一篇文章 - 如果我标记错误或标记错误,请轻松一下:P
在微软新的ASP.NET MVC框架中,似乎有两件事可能会导致您的内容在多个网址上提供(Google会对此进行惩罚,并导致您的PageRank在其中分割):
您可以设置默认控制器/操作以提供对域根目录的请求。假设我们选择HomeController / Index。我们最终提供了以下提供相同内容的网址:
现在,如果人们开始链接到这两者,那么PageRank将被拆分。谷歌也会认为它是重复内容并惩罚其中一个,以避免重复结果。
除此之外,这些网址不区分大小写,因此我们实际上也为这些网址获取了相同的内容:
所以,问题是......我如何避免这些处罚?我想:
可能的?
答案 0 :(得分:11)
我也在研究这个问题。我显然会顺从ScottGu。我谦卑地提供了解决这个问题的方法。
将以下代码添加到 global.asax :
protected void Application_BeginRequest(Object sender, EventArgs e)
{
// If upper case letters are found in the URL, redirect to lower case URL.
if (Regex.IsMatch(HttpContext.Current.Request.Url.ToString(), @"[A-Z]") == true)
{
string LowercaseURL = HttpContext.Current.Request.Url.ToString().ToLower();
Response.Clear();
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location",LowercaseURL);
Response.End();
}
}
一个很好的问题!
答案 1 :(得分:9)
除了在这里发帖,我还通过电子邮件向ScottGu发送电子邮件,看他是否有好的回复。他给出了一个为路由添加约束的示例,因此您只能回复小写网址:
public class LowercaseConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route,
string parameterName, RouteValueDictionary values,
RouteDirection routeDirection)
{
string value = (string)values[parameterName];
return Equals(value, value.ToLower());
}
在寄存器路由方法中:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "home", action = "index", id = "" },
new { controller = new LowercaseConstraint(), action = new LowercaseConstraint() }
);
}
这是一个开始,但是我希望能够从Html.ActionLink和RedirectToAction等方法更改链接的生成以匹配。
答案 2 :(得分:4)
凹凸!
MVC 5 现在支持仅生成小写网址和常见的尾部斜杠政策。
public static void RegisterRoutes(RouteCollection routes)
{
routes.LowercaseUrls = true;
routes.AppendTrailingSlash = false;
}
同样在我的申请中,以避免在不同的域名/ Ip / Letter Casing等上重复内容...
我倾向于根据 PrimaryDomain - 协议 - 控制器 - 语言 - 动作强>
public static String GetCanonicalUrl(RouteData route,String host,string protocol)
{
//These rely on the convention that all your links will be lowercase!
string actionName = route.Values["action"].ToString().ToLower();
string controllerName = route.Values["controller"].ToString().ToLower();
//If your app is multilanguage and your route contains a language parameter then lowercase it also to prevent EN/en/ etc....
//string language = route.Values["language"].ToString().ToLower();
return String.Format("{0}://{1}/{2}/{3}/{4}", protocol, host, language, controllerName, actionName);
}
然后,如果当前请求网址与之匹配,您可以使用 @Gabe Sumner 答案重定向到您操作的规范网址。
答案 3 :(得分:2)
我相信有更好的答案。如果您在页面中添加规范链接,请执行以下操作:
<link rel="canonical" href="http://mydomain.com/Home/Index"/>
然后谷歌只显示其结果中的规范页面,更重要的是,所有谷歌善良都会转到该页面而不会受到惩罚。
答案 4 :(得分:1)
和你一样,I had the same question;除了我不愿满足于全小写的网址限制,并且不喜欢canonical
方法(嗯,它很好,但不是单独的)。
我找不到解决方案,所以我们wrote and open-sourced一个redirect class。
使用它很容易:控制器类中的每个GET方法都需要在开头添加这一行:
Seo.SeoRedirect(this);
SEO重写类自动使用C#5.0的Caller Info属性来完成繁重的工作,使上面的代码严格复制粘贴。
正如我在链接的SO Q&amp; A中所提到的,我正在研究如何将其转换为属性,但就目前而言,它可以完成工作。
代码将强制一个URL的案例。该案例将与控制器方法的名称相同 - 您可以选择是否要全部大写,全部更低,或两者兼而有(CamelCase适用于URL)。它将针对不区分大小写的匹配发出301重定向,并将结果缓存在内存中以获得最佳性能。它还会重定向尾随反斜杠(强制执行索引列表,否则强制执行),并删除通过默认方法名称(库存ASP.NET MVC应用程序中的Index
)访问的重复内容。
答案 5 :(得分:0)
我真的不知道你8年后会有什么感受但现在ASP MVC 5支持易于记忆路线的属性路由,并解决了SEO友好网站的重复内容问题
添加 routes.MapMvcAttributeRoutes();在RouteConfig中,然后为每个操作定义一个且唯一的路由,如
[Route("~/")]
public ActionResult Index(int? page)
{
var query = from p in db.Posts orderby p.post_date descending select p;
var pageNumber = page ?? 1;
ViewData["Posts"] = query.ToPagedList(pageNumber, 7);
return View();
}
[Route("about")]
public ActionResult About()
{
return View();
}
[Route("contact")]
public ActionResult Contact()
{
return View();
}
[Route("team")]
public ActionResult Team()
{
return View();
}
[Route("services")]
public ActionResult Services()
{
return View();
}
答案 6 :(得分:0)
基于Gabe Sumner的回答,但没有重定向JS,图像和其他内容。仅适用于控制器动作。这个想法是在我们已经知道路由的路由时,在管道的后面进行重定向。为此,我们可以使用ActionFilter。
public class RedirectFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var url = filterContext.HttpContext.Request.Url;
var urlWithoutQuery = url.GetLeftPart(UriPartial.Path);
if (Regex.IsMatch(urlWithoutQuery, @"[A-Z]"))
{
string lowercaseURL = urlWithoutQuery.ToString().ToLower() + url.Query;
filterContext.Result = new RedirectResult(lowercaseURL, permanent: true);
}
base.OnActionExecuting(filterContext);
}
}
请注意,上面的过滤器不会重定向或更改查询字符串的大小写。
然后将ActionFilter全局绑定到所有动作,方法是将其添加到GlobalFilterCollection。
filters.Add(new RedirectFilterAttribute());
在RouteCollection上仍将LowercaseUrls属性设置为true是个好主意。