Asp.net mvc - разные представления требуют разного метатега на странице <head> внутри макета
Я хотел бы остановить показ некоторых моих страниц в результатах поиска. Я понимаю, что я добавляю следующее в раздел <head>
страницы:
<meta name="robots" content="noindex,nofollow"/>
Проблема заключается в том, что мои страницы используют общую страницу макета. Что-то вроде:
@{
Layout = "~/Views/Shared/_VanillaLayout.cshtml";
}
Внутри страницы макета находится раздел главы со множеством ссылок, скриптов и метатег. Я не хочу дублировать это для индексируемых и неиндексируемых страниц.
Из моего исследования я обнаружил, что: -
- Наличие нескольких
<head>
разделов плохое.
- Наличие метатега робота вне головы плохой.
- Использование robots.txt больше, чем я хочу, и плохой.
- Попытка передать модель в макет - это немного избыточный (нужно, чтобы все модели наследовались от какой-то базы, а многие страницы чисто представлены и даже не имеют модели) и плохо.
Надеюсь, что у меня что-то не хватает, и есть хороший (неплохой) способ сделать это, или один из подходов, о которых я упомянул выше, не так уж и плох.
Ответы
Ответ 1
Мне кажется, что самый простой способ - определить раздел в теге <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. Кроме того, помеченное как не обязательное означает, что вам нужно обновлять страницы, которые вы хотите не индексировать, и не нужно устанавливать переменную на каждой странице вашего приложения.
Ответ 2
Вы можете добавить следующее условие с метатегом к элементу <head>
в вашем общем макете:
<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
@if (PageData["DisableIndexing"])
{
<meta name="robots" content="noindex,nofollow"/>
}
...
</head>
<body>
...
</body>
Этот флаг будет установлен как отключенный по умолчанию в вашем основном файле _ViewStart.cshtml
, который находится в папке "Представления". Это означает, что по умолчанию ни одна страница не добавит этот метатег. Это будет файл _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 в макет, но код немного уродлив, так как у вас нет прямого доступа к ViewBag в ViewStart. См. этот ответ, если вы предпочитаете использовать ViewBag.
Ответ 3
Если вы не определяете какой-либо метатег на странице макета, и вы просто хотите добавить его с вашей страницы, вы можете сделать следующее.
в вашей странице макета _VanillaLayout.cshtml в разделе head используйте @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">
}
Таким образом, вы можете определить специфический метатег и другую вещь отдельно на своей странице.
Ответ 4
Попробуйте с Jquery, на странице, которую вы не хотите индексировать, добавьте
$('head').append('<meta name="robots" content="noindex,nofollow"/>');
Edit:
может быть другая попытка (в соответствии с этим Будет ли Googlebot сканировать изменения в DOM с помощью JavaScript?), чтобы попробовать с помощью простого javascript вместо jquery library
document.getElementsByTagName('head')[0].appendChild('<meta name="robots" content="noindex,nofollow"/>');
Ответ 5
Старый вопрос, но если это может кому-то помочь, в верхнем макете мне пришлось использовать:
<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> *@
}