Search code examples
asp.net-mvcrazorwebformsviewbag

ViewBag not declared in hybrid Webforms/MVC project


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.


Solution

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