我想在我的网站上使用规范网址。我在互联网上阅读了一些关于它的内容,但我正在寻找一种解决方案,它将自动为我的运行时生成规范并将其添加到返回浏览器的html代码中。
我已经在互联网上找到了一个使用属性的例子,但这不是我想要的。使用属性我仍然决定哪个页面应该是规范或不是我自己,我希望每个页面都有一个自动生成的页面。我认为应该有(现有的)解决方案吗?我正在努力寻找一个好的榜样,所以任何帮助都会受到赞赏。
答案 0 :(得分:21)
Razor:
我为HtmlHelper
制作了一个扩展方法:
public static MvcHtmlString CanonicalUrl(this HtmlHelper html, string path)
{
if (String.IsNullOrWhiteSpace(path))
{
var rawUrl = html.ViewContext.RequestContext.HttpContext.Request.Url;
path = String.Format("{0}://{1}{2}", rawUrl.Scheme, rawUrl.Host, rawUrl.AbsolutePath);
}
path = path.ToLower();
if (path.Count(c => c == '/') > 3)
{
path = path.TrimEnd('/');
}
if (path.EndsWith("/index"))
{
path = path.Substring(0, path.Length - 6);
}
var canonical = new TagBuilder("link");
canonical.MergeAttribute("rel", "canonical");
canonical.MergeAttribute("href", path);
return new MvcHtmlString(canonical.ToString(TagRenderMode.SelfClosing));
}
获取当前网址
public static MvcHtmlString CanonicalUrl(this HtmlHelper html)
{
var rawUrl = html.ViewContext.RequestContext.HttpContext.Request.Url;
return CanonicalUrl(html, String.Format("{0}://{1}{2}", rawUrl.Scheme, rawUrl.Host, rawUrl.AbsolutePath));
}
调用Razor View:
@Html.CanonicalUrl()
答案 1 :(得分:4)
MVC 5提供了为您的路线生成小写URL的新选项。我的路线配置如下所示:
public static class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
// Imprive SEO by stopping duplicate URL's due to case or trailing slashes.
routes.AppendTrailingSlash = true;
routes.LowercaseUrls = true;
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}
}
使用此代码,您不再需要规范化URL,因为这样做是为您完成的。如果您使用HTTP和HTTPS URL并且想要一个规范URL,则可能会出现唯一的问题。在这种情况下,使用上述方法非常容易,并用HTTPS替换HTTP,反之亦然。
答案 2 :(得分:3)
虽然它提供了制作Canonical url的好方法,但已接受的答案。
它完全破坏了使用规范标签的意义!
为什么规范标签存在?
当Google抓取您的网站并发现重复内容会对您造成不利影响时。
您网站中的同一页面可以通过各种途径访问。
http://yourdomain.com/en
https://yourClientIdAt.YourHostingPacket.com/
http://195.287.xxx.xxx //Your server Ip
https://yourdomain.com/index
http://www.yourdomain.com/
http://www.yourdomain.com/index .....etc... etc..
Google会在各种路径中找到相同的内容,从而重复内容,从而受到惩罚。
虽然最佳做法是使用301重定向,并且只有1个链接指向相同的网页,这很痛苦......
这就是为什么 rel =“canonical”已经创建的原因。它是一种告诉爬虫的方法
“嘿,这不是一个不同的页面,这是www.mydomain.index页面 你之前搜索过....规范标签中的链接是正确的!“
然后,同一网页不会被多次抓取作为另一个网页。
通过动态生成您刚才说的网址的规范链接....
<link href="http://yourdomain.com" rel="canonical">
是的....这是一个不同的页面爬这个也....<link href="http://www.yourdomain.com/index" rel="canonical">
这是另一个......而这一个......
因此,为了拥有一个正常工作的标准标记,您必须为每个具有不同内容的页面生成相同的完全链接。确定您的主域(www.etc.com),协议(Https / Http)和Letter Casing(/ Index,/ index)并生成唯一的链接标识单个页面。 这是您的控制器 / 操作(可能还有语言)组合。 因此,您可以从路线数据中提取这些值。
public static TagBuilder 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();
string finalUrl = String.Format("{0}://{1}/{2}/{3}/{4}", protocol, host, language, controllerName, actionName);
var canonical = new TagBuilder("link");
canonical.MergeAttribute("href", finalUrl);
canonical.MergeAttribute("rel", "canonical");
return canonical;
}
为了让您的HtmlHelper与您的会议产生一致的链接@Muhammad Rehan Saeed回答说。
然后,为了为所有页面生成Canonical标签,您必须制作 HtmlHelper扩展
public static MvcHtmlString CanonicalUrl(this HtmlHelper html,string host,string protocol)
{
var canonical = GetCanonicalUrl(HttpContext.Current.Request.RequestContext.RouteData,host,protocol);
return new MvcHtmlString(canonical.ToString(TagRenderMode.SelfClosing));
}
@Html.CanonicalUrl("www.mydomain.com", "https");
或为控制器实施操作过滤器属性。 (我使用这种方法来处理同一个应用程序上的多个域等更复杂的场景......)
public class CanonicalUrl : ActionFilterAttribute
{
private string _protocol;
private string _host;
public CanonicalUrl(string host, string protocol)
{
this._host = host;
this._protocol = protocol;
}
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
var canonical = GetCanonicalUrl(filterContext.RouteData,_host,_protocol);
filterContext.Controller.ViewBag.CanonicalUrl = canonical.ToString();
}
}
}
控制器内的用法
[CanonicalUrl("www.yourdomain.com","https")]
public class MyController : Controller
然后我在_Layout.chtml上使用它并完成了!
@Html.Raw(ViewBag.CanonicalUrl)
答案 3 :(得分:1)
问题解决了。修复了它编写我自己的html帮助程序,它通过从请求中获取URL来生成规范URL。这是否使用了来自this主题的信息。