Why can't _ViewStart.cshtml access the ViewBag

2019-03-22 14:39发布

问题:

I have the default _ViewStart.cshtml in my /Views folder. I'd like to be able to access my ViewBag object so I can set the default title for all my views.

However, with:

@{
    Layout = "~/Views/Shared/SiteLayout.cshtml";
    ViewBag.Title = "bytecourse - Online Courses in Technology";
}

I get "The name 'ViewBag' does not exist in the current context" as a runtime error.

What do I need to do?

回答1:

In short... Use the controller's view bag.

ViewContext.Controller.ViewBag.MyVar = "myVal";

and

@ViewContext.Controller.ViewBag.MyVar

===============================================================

There is good information here: http://forums.asp.net/post/4254825.aspx

===============================================================

Generally, ViewData["StoreName"] is same as ViewBag.StoreName

Also, Controller.ViewData["StoreName"] = Controller.StoreName = ViewContext.Controller.ViewBag.StoreName =ViewContext.Controller.ViewData["StoreName"]

But every view and partial view gets its own instance of viewdata.

http://jeffreypalermo.com/blog/viewdata-mechanics-and-segmentation-excerpt-from-asp.net-mvc-in-action/

===============================================================

There is a another solution here: https://stackoverflow.com/a/4834382/291753

===============================================================



回答2:

hmm, you can access ViewBag via ViewData, e.g. ViewContext.ViewData["Title"].

So if you set ViewBag data in an action filter for example, you can pull it out from _ViewStart.cshtml using ViewContext.ViewData["Title"].

But I tried to assign a value using ViewContext.ViewData["Key"] = value; and it doesn't seem to persist to the actual view.



回答3:

You can achieve this using Partial views. Put all your Title related common code in a Partial View called Title.cshtml in the shared folder. In the _viewstart simply call the Partial view.

_ViewStart.cshtml:

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}
@Html.Partial("Title")

~/Shared/Title.cshtml:

@{
 ViewBag.Title = "bytecourse - Online Courses in Technology"; 
}


回答4:

You could use sections in your _Layout if you want to set a default title:

<title>
    @if (IsSectionDefined("Title"))
    {
        @RenderSection("Title")
    }
    else
    {
        @:bytecourse - Online Courses in Technology
    }
</title>

and inside views you could override it:

@section Title {
    Overriden title
}

One more reason not to use ViewBag :-)



回答5:

Its not 100% clean but see a workaround using PageData or a bit of enumeration at:

How do I set ViewBag properties on _ViewStart.cshtml?



回答6:

You can create one layout page which is using your Viewbag data and add layout to your blank _ViewStart page it will work

on ViewStart.cshtml

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