사례에 민감하지 않은 URL 및 기본값으로 인해 ASP.NET MVC의 중복 콘텐츠를 피하려면 어떻게해야합니까?
-
05-07-2019 - |
문제
편집하다: 이제이 문제를 실제로 해결해야합니다. 조금 더 조사를했으며 중복 콘텐츠를 줄이기 위해 여러 가지를 생각해 냈습니다. 내 블로그에 자세한 코드 샘플을 게시했습니다. ASP.NET MVC로 중복 컨텐츠를 줄입니다
첫 번째 게시물 - 내가 이것을 잘못 표시했거나 잘못 표시되면 쉽게 갈 수 있습니다.
Microsoft의 새로운 ASP.NET MVC 프레임 워크에는 여러 URL에서 콘텐츠를 제공 할 수있는 두 가지가있는 것으로 보입니다 (Google에 대한 처벌을 받고 PageRank가 분리 될 수있는 방법) :
- 사례에 민감한 URL
- 기본 URL
도메인의 루트에 대한 요청을 위해 기본 컨트롤러/작업을 설정할 수 있습니다. HomeController/Index를 선택한다고 가정 해 봅시다. 우리는 동일한 컨텐츠를 제공하는 다음 URL로 끝납니다.
- mydomain.com/
- mydomain.com/home/index
이제 사람들 이이 두 가지에 연결을 시작하면 PageRank가 분할됩니다. Google은 또한 컨텐츠 중복을 고려하고 결과의 중복을 피하기 위해 그 중 하나를 불이익시킬 것입니다.
또한 URL은 사례에 민감하지 않으므로 실제로 이러한 URL에 대해 동일한 컨텐츠를 얻습니다.
- mydomain.com/home/index
- mydomain.com/home/index
- mydomain.com/home/index
- mydomain.com/home/index
- (목록은 계속됩니다)
그렇다면 질문은 ... 이러한 처벌을 어떻게 피합니까? 나는 원한다 :
- 기본 조치를 동일한 URL로 리디렉션 (301 상태)에 대한 모든 요청
- 모든 URL은 사례에 민감합니다
가능한?
해결책
충돌!
MVC 5 이제 소문자 URL 및 일반적인 후행 슬래시 정책 만 생산하는 것을 지원합니다.
public static void RegisterRoutes(RouteCollection routes)
{
routes.LowercaseUrls = true;
routes.AppendTrailingSlash = false;
}
또한 다른 도메인/IP/레터 케이싱 등의 중복 콘텐츠를 피하기 위해 내 응용 프로그램에서 ...
나는 a 1 차 도메인 - 규약 - 제어 장치 - 언어 - 동작
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 's 현재 요청 URL이 일치하지 않으면 동작의 표준 URL로 리디렉션하려면 답변하십시오.
다른 팁
나는 이것도 작업하고 있었다. 나는 분명히 이것에 대해 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();
}
}
좋은 질문!
여기에 게시 할뿐만 아니라 Scottgu에게 이메일을 보내서 좋은 답변이 있는지 확인했습니다. 그는 경로에 제약 조건을 추가하기위한 샘플을 주 었으므로 소문자 URL에만 응답 할 수 있습니다.
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() }
);
}
시작이지만 'D는 html.actionLink 및 REDirectToaction과 같은 메소드에서 링크 생성을 변경할 수 있기를 원합니다.
나는 이것에 대한 더 나은 대답이 있다고 생각합니다. 페이지 헤드에 정식 링크를 넣는 경우 다음과 같습니다.
<link rel="canonical" href="http://mydomain.com/Home/Index"/>
그런 다음 Google은 결과에 표준 페이지 만 표시되며 더 중요한 것은 모든 Google Goodness가 페널티없이 해당 페이지로 이동합니다.
너 같이, 나는 같은 질문을했다; 내가 All-LowerCase URL 제한을 정착시키지 않으려는 것을 제외하고는 canonical
접근하십시오.
해결책을 찾을 수 없었습니다 작성하고 열린 소스 ㅏ 클래스 리디렉션.
그것을 사용하는 것은 쉽습니다. 컨트롤러 클래스의 각 GET 메소드는 처음 에이 한 줄만 추가해야합니다.
Seo.SeoRedirect(this);
SEO Rewrite 클래스는 자동으로 C# 5.0의 발신자 정보 속성을 사용하여 무거운 리프팅을 수행하여 위의 코드를 엄격하게 카피 앤 페이스트합니다.
링크 된 So Q & A에서 언급했듯이, 나는 이것을 속성으로 변환하기 위해 노력하고 있지만 지금은 작업을 완료합니다.
코드는 URL에 대한 한 가지 사례를 강요합니다. 이 사례는 컨트롤러 메소드의 이름과 동일합니다. 모든 캡을 원하는 경우 선택하거나 모두 낮거나 두 가지 혼합을 원하는 경우 (Camelcase는 URL에 좋습니다). 케이스 감수성 일치에 대한 301 리디렉션을 발행하고 최상의 성능을 위해 결과를 메모리에 캐시합니다. 또한 후행 백 슬래시 (인덱스 목록을 위해 시행, 그렇지 않으면 시행)를 리디렉션하고 기본 메소드 이름을 통해 액세스 할 수있는 중복 컨텐츠를 제거합니다.Index
재고 ASP.NET MVC 앱).
나는 당신이 8 년 후에 어떻게 느끼는지 잘 모르지만 이제 ASP MVC 5는 기억하기 쉬운 경로를 위해 속성 라우팅을 지원하고 SEO 친화적 인 사이트에 대한 중복 컨텐츠 문제를 해결합니다.
LOPES.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();
}
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에 추가하여 ActionFilter를 모든 작업에 바인딩하십시오.
filters.Add(new RedirectFilterAttribute());
소문자 속성을 계속 수집 할 때 여전히 true로 설정하는 것이 좋습니다.