asp.net mvc - 不同的视图在内部布局页面中需要不同的元标记

时间:2014-01-08 10:45:11

标签: html asp.net-mvc razor

我想阻止我的一些网页显示在搜索结果中。我的理解是,我将以下内容添加到页面的<head>部分:

<meta name="robots" content="noindex,nofollow"/>

问题是我的网页使用了常见的布局页面。类似的东西:

@{
    Layout = "~/Views/Shared/_VanillaLayout.cshtml";
}

布局页面内部是头部,包含大量链接,脚本和元标记。我不想为可索引和不可索引的页面复制它。

根据我的研究,我发现: -

  • 拥有多个<head>部分 is bad
  • 将机器人元标记置于头部 is bad
  • 之外
  • 使用robots.txt比我想要的更多, is bad
  • 尝试将模型传递到布局中有点过分(需要所有模型从一些基础继承,许多页面纯粹是演示文稿,甚至没有模型)和 is bad 即可。

希望我错过了一些东西并且有一种好的(非坏的)方法可以做到这一点,或者我上面提到的其中一种方法毕竟不是那么糟糕。

6 个答案:

答案 0 :(得分:67)

在我看来,最简单的方法是在布局文件的<head>标记中定义一个部分,您可以选择在其中填充您的视图中的数据

<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title - My ASP.NET MVC Application</title>
    <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
    <meta name="viewport" content="width=device-width" />
    <!-- Adding a RenderSection here, mark it as not required-->
    @RenderSection("AdditionalMeta", false)
    @Styles.Render("~/Content/css")
</head>

现在,在您需要添加其他元数据的任何视图中,只需在视图文件的结尾/开头(模型声明之后)添加以下代码

@section AdditionalMeta
{
    <meta name="robots" content="noindex,nofollow"/>
}

由于所有Razor内容都是在服务器端进行处理的,因此a)使用JS附加项目时会出现问题,因为有些爬虫没有实现JS,b)没有后期附加到<head>标签/ etc。此外,标记为不需要意味着您只需要更新您不想编入索引的页面,而不必在应用程序的每个页面上设置变量。

答案 1 :(得分:8)

您可以使用元标记将以下条件添加到公共布局中的<head>元素:

<!DOCTYPE html>
<html>
<head>
    <title>@ViewBag.Title</title>
    @if (PageData["DisableIndexing"])
    {
        <meta name="robots" content="noindex,nofollow"/>  
    }    
    ...
</head>
<body>
    ...
</body>

默认情况下,该标志将在主_ViewStart.cshtml文件中设置为禁用,即Views文件夹中的那个。这意味着默认情况下,没有页面会添加该元标记。这将是_ViewStart文件:

@{
    Layout = "~/Views/Shared/_VanillaLayout.cshtml";
    PageData["DisableIndexing"] = false;
}

最后,在要禁用索引的页面上,您只需要覆盖该标志。例如,如果Foo视图不允许索引,则可以执行以下操作:

@model MyNamespace.MyFooModel

@{
    ViewBag.Title = "Foo";
    PageData["DisableIndexing"] = true;
}
...

如果某个文件夹中的所有视图都应禁用索引,您甚至可以将另一个_ViewStart.cshtml文件添加到您刚设置的文件夹中PageData["DisableIndexing"] = true;

作为旁注,您还可以使用ViewBag将数据从_ViewStart传递到布局,但代码有点难看,因为您无法直接访问ViewStart中的ViewBag。如果您更喜欢使用ViewBag,请参阅this answer

答案 2 :(得分:7)

如果您没有在“布局”页面中定义任何元标记,并且只是想从页面添加,那么您可以执行以下操作。

在您的布局页面_VanillaLayout.cshtml的头部下使用@RenderSection如下

<head>
<meta charset="utf-8">    
@RenderSection("SeoRender", false)
</head>

现在在您的视图页面中按照以下方式执行

@{
Layout = "~/Views/Shared/_VanillaLayout.cshtml";
}

@section SeoRender{
@{        
<title>testTitle</title>
<meta name="keyword" content="testkeyword">
<meta name="description" content="testdescription">
<meta name="author" content="testauthor">   
}

因此,您可以在页面中单独定义特定元标记和其他内容。

答案 3 :(得分:0)

尝试使用Jquery,在您不想编入索引的页面中,添加

$('head').append('<meta name="robots" content="noindex,nofollow"/>');

编辑:

另一个尝试可能是(根据此Will Googlebot crawl changes to the DOM made with JavaScript?)尝试使用简单的javascript而不是jquery库

document.getElementsByTagName('head')[0].appendChild('<meta name="robots" content="noindex,nofollow"/>');

答案 4 :(得分:0)

老问题,但是如果它可以帮助某人,在上层布局中,我必须使用:

<head>
    @RenderSection("MySection", required:false)
</head>

然后,在每个 嵌套的布局中,我不得不重新定义我的部分:

@section MySection {
    @RenderSection("MySection", false)
}

最后,我在.cshtml视图中定义了我的部分:

@section MySection{
    <meta name="robots" content="@Model.MetaContent"/>  

    @* or any other tag going to <head> *@
}

答案 5 :(得分:0)

还是一个老问题,但是我想出了一个非常简单的方法来做到这一点:

  1. 定义一些元属性:
<meta property="og:type" content="website"/>
<meta property="og:url" content="https://illusive.azurewebsites.net/"/>
<meta property="og:image" content="https://illusive.azurewebsites.net/favicon.ico"/>
  1. 在每个页面上定义要不同的自定义属性(在您的父_Layout.cshtml中):
<meta property="og:title" content="@ViewData["Title"]"/>
<meta property="og:description" content="@ViewData["Description"]"/>
  1. 为您的不同布局定义ViewData元素:

(在Index.html内部)

@model IndexModel
@{
    ViewData["Title"] = "Homepage";
    ViewData["Description"] = "Home Page";
}

(在Error.cshtml内部)

@model ErrorModel
@{
    ViewData["Title"] = "Error";
    ViewData["Description"] = "An error has occurred!";
}

这应该是一种轻松自定义元标记的方法,而不必使用部分或任何乏味的代码块。