asp.net mvc - different views need different meta tag in <head> inside layout page

It seems to me the easiest way would be to define a section in the <head> tag of your layout file that you can choose to populate with data in your views

<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>

Now, in any view in which you need to add additional meta data, simply add the following code at the end/beginning (after model declarations) of your view file

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

Since all of the Razor stuff is processed server side, there would be no issues in a) having JS append items given that some crawlers do not implement JS and b)no late appending to <head> tag/etc. Also, being marked as not required means that you only have to update the pages that you want to not be indexed and not have to set a variable on every single page in your application.


You can add the following conditional with the meta-tag to the <head> element in your common layout:

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

That flag will be set as disabled by default in your main _ViewStart.cshtml file, the one in the Views folder. That would mean by default no page will add that meta tag. This will be the _ViewStart file:

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

Finally, on pages where you want to disable indexing you just need to override that flag. For example if the Foo view should not allow indexing, you would do:

@model MyNamespace.MyFooModel

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

If all the views within a certain folder should disable indexing, you could even add another _ViewStart.cshtml file to that folder where you would just set PageData["DisableIndexing"] = true;

As a side note, you could also use the ViewBag to pass data from the _ViewStart to the layout, but code is a bit ugly as you don't have direct access to the ViewBag in the ViewStart. See this answer if you prefer to use the ViewBag.


If you are not defining any meta tag in Layout page and you simply want to add from your Page then you can do as following.

in your layout page _VanillaLayout.cshtml under head section use @RenderSection as following

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

Now in your view page do following way

@{
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">   
}

So this you can define specifican meta tag and other thing individually in your page.