I have an existing webforms project (.net 4.5.1) that I just added MVC to (I just created a new MVC project using Individual authentication and copied all of the bits to the Webforms project).
When I navigate to something like Sitename/Home/index, it works fine and renders the page. However, when I navigate to Sitename/Account/Login I get the following runtime error:
error BC30451: 'ViewBag' is not declared. It may be inaccessible due to its protection level.
It seems to happen on views with models.
I have found other answers indicating to check the version of MVC, and all of my MVC DLLs are up to date (version 5.2.3.0), and latest Razor related stuff too. I also confirmed the web.config file exists in the View directory. I also did the standard paranoid things like doing a full clean and recompile, restarting Visual Studio, etc.
I tried a new test action on the same controller, the only difference being that the failing one has a model. Here are the two actions (MyTest works, Login doesn't):
<AllowAnonymous>
Function MyTest() As ActionResult
ViewBag.ReturnUrl = "testReturnUrl"
Return View()
End Function
'
' GET: /Account/Login
<AllowAnonymous>
Public Function Login(returnUrl As String) As ActionResult
ViewBag.ReturnUrl = returnUrl
Return View()
End Function
Here is the MyTest View:
@Code
ViewBag.Title = "MyTest"
End Code
<h2>MyTest</h2>
Hiya!!
Here is the Login view (the default one that comes with Visual Studio templates, so I've only included the first few lines):
@ModelType LoginViewModel
@Code
ViewBag.Title = "Log in"
End Code
<h2>@ViewBag.Title.</h2>
.
.
.
And here is my Views/Web.config:
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
</namespaces>
</pages>
</system.web.webPages.razor>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/>
</httpHandlers>
<!--
Enabling request validation in view pages would cause validation to occur
after the input has already been processed by the controller. By default
MVC performs request validation before a controller processes the input.
To change this behavior apply the ValidateInputAttribute to a
controller or action.
-->
<pages
validateRequest="false"
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<controls>
<add assembly="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
</controls>
</pages>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="BlockViewHandler"/>
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
</handlers>
</system.webServer>
</configuration>
Any thoughts on a fix or a workaround? I'm pretty sure this is not specific to ViewBag, it is likely just the first thing that fails.
It seems it is related to namespaces. Since the webforms app is annoyingly written in VB, I'm wondering if the namespace convention in VB (where subfolders don't automatically get a new namespace) is causing a problem here?
Anyway, I added the project name as a namespace to the Views/Web.config file as below, then restarted Visual Studio (otherwise intellisense still didn't see it) and it works fine now.
I might have added the namespace in the Properties->References list too, not too sure.
Here is the config namespace section now:
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="MyProjectName" />
</namespaces>
</pages>