为mvc3 Web应用程序自动生成规范

时间:2011-03-22 19:29:08

标签: c# asp.net asp.net-mvc-3 seo

我想在我的网站上使用规范网址。我在互联网上阅读了一些关于它的内容,但我正在寻找一种解决方案,它将自动为我的运行时生成规范并将其添加到返回浏览器的html代码中。

我已经在互联网上找到了一个使用属性的例子,但这不是我想要的。使用属性我仍然决定哪个页面应该是规范或不是我自己,我希望每个页面都有一个自动生成的页面。我认为应该有(现有的)解决方案吗?我正在努力寻找一个好的榜样,所以任何帮助都会受到赞赏。

4 个答案:

答案 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主题的信息。