After Windows update "The type or namespace name 'Html' does not exist in the namespace 'System.Web.Mvc'"

asp.netasp.net MvcWindows Update

asp.net Problem Overview


I did a Windows update and afterwards my asp.net mvc 5 application will no longer load complaining about

CS0234: The type or namespace name 'Html' does not exist in the namespace 'System.Web.Mvc'

indicating my views web.config is at fault

  <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.0.0.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.Optimization"/>
        <add namespace="System.Web.Routing" />
        <add namespace="Ogre.Extensions" />
        <add namespace="Newtonsoft.Json"/>
      </namespaces>
    </pages>
  </system.web.webPages.razor>

Now this is very confusing. In my project itself I can see the Html namespace, opening my assembly in ILSpy I can navigate to the bound System.Web.Mvc and I can it as well, and the fusion log is not showing any suspicious binding errors.

It's as if just my views are getting bound (successfully) to an old version of Mvc. Why would that ever happen? How can I fix it?

Let me be clear that there have been no configuration or even code changes. This is all on my dev machine on IISExpress. It was running, I did the update and rebooted and now it is no longer running.

Here are my recent installs from the update. I could start removing them one by one, but I want to know what is actually going wrong as it feels like I'm missing part of the story.

Installs from the update

asp.net Solutions


Solution 1 - asp.net

Holy crap, thanks to @Nevada-Williford for the hint. Going in and setting my System.Web.Mvc reference to <Private>True</Private> (Copy Local = True) fixed it. Note, that before the update everything was working, after the update I had to modify my csproj to get it working again.

Working theory on what's going on:

Copy Local = True and <Private>True</Private> used to be almost, but not exactly, the same thing. The former was a Visual Studio setting, the latter an msbuild setting. If the msbuild setting was absent, the Visual Studio setting would be applied (as long as you were in VS). In this update I think they changed it so Copy Local just reflects the presence attribute.

In our project we do not have that attribute set explicitly but Copy Local = True so prior to the update System.Web.Mvc.dll gets copied to the bin directory. After the update, since the attribute is missing Copy Local shows False and you have to set it to True to make sure you get a local copy.

Manually setting Copy Local = True (or adding that xml element to msbuild) fixes the issue.

Edit: While this appears to be the answer to the specific question, anyone coming here should read the comment thread and other answers - especially dmatson's - for more context, caveats, and related bugs.

Solution 2 - asp.net

This was broken for any users without CopyLocal=true (or, in MSBuild speak, <Private>True</Private>) by MS14-059. MVC templates do set <Private>True</Private> by default, but if you use NuGet to update the MVC version, you lose that setting (see NuGet bug #4344).

There are two aspects to the problem:

  1. Razor doesn't include a reference to MVC by default, so its compilation won't work unless some version of the MVC DLL exists in your bin folder.
  2. If you deploy to a separate machine that doesn't have this update installed, the MVC DLL isn't included in your output anymore, so MVC will be missing.

You're seeing problem #1. To resolve both problems, I'd recommend making both of the following changes:

  1. Add the following configuration to Views\Web.config:

     <system.web>
       <compilation>
         <assemblies>
           <add assembly="System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
         </assemblies>
       </compilation>
     </system.web>
    
  2. Set CopyLocal=true in the VS UI for the project reference, or manually add the following line below in the Reference in your .csproj file:

     <Private>True</Private>
    

So your full reference should look something like the following:

<Reference Include="System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
  <Private>True</Private>
  <HintPath>..\..\packages\Microsoft.AspNet.Mvc.5.0.0\lib\net45\System.Web.Mvc.dll</HintPath>
</Reference>

Note that NuGet will remove the CopyLocal/Private setting if you update packages again in the future. (For example, if you update to MVC 5.2 today). If that version of MVC is ever GAC'd, problem #1 above will not recur as long as you've added the configuration in step A above, but problem #2 could still happen again. To ensure this doesn't happen in the future, I'd recommend manually setting CopyLocal back to true any time you do a NuGet package update.

Solution 3 - asp.net

  1. You can go to References of current Project.
  2. Right click in dll System.Web.Mvc and choose Properties
  3. A Properties window will open
  4. Change Copy Local to True

Solution 4 - asp.net

Setting CopyLocal=true did not help. Cleaning the solution then closing it and reopening it again worked. You might need to close the entire Visual Studio instance as well.

Solution 5 - asp.net

This appears to have been caused by a Windows Update (KB2990942) to fix security vulnerablity MS14-059, allowing security feature bypass. Our builds stopped working on our build server after the Windows Update was installed, and updating the csproj files to use 4.0.0.1 for the System.Web.Mvc reference fixed the issue.

Microsoft's description of the vulnerability is:

> The vulnerability could allow security feature bypass if an attacker convinces a user to click a specially crafted link or to visit a webpage that contains specially crafted content designed to exploit the vulnerability. In a web-based attack scenario, an attacker could host a specially crafted website that is designed to exploit the vulnerability through a web browser, and then convince a user to view the website. The attacker could also take advantage of compromised websites and websites that accept or host user-provided content or advertisements. These websites could contain specially crafted content that could exploit the vulnerability. In all cases, however, an attacker would have no way to force users to view the attacker-controlled content. Instead, an attacker would have to convince users to take action, typically by getting them to click a link in an email message or in an Instant Messenger message that takes them to the attacker's website, or by getting them to open an attachment sent through email.

Solution 6 - asp.net

As well as setting CopyLocal=true in the project reference you may also need to change the Web.Config file like so...

  <dependentAssembly>
    <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.1" />
  </dependentAssembly>

Notice the newVersion="4.0.0.1". This worked for me, and I hope it helps a few people out as well.

Saves updating the MVC framework on any test/production servers.

Cheers Microsoft. You're the best!

Your attempt to make me look incompetent in front of my clients has been foiled yet again!

Solution 7 - asp.net

As well as setting CopyLocal=true in the project reference you may also need to change the Web.Config file like so...

<dependentAssembly>
  <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
  <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.1" />
</dependentAssembly>

I added culture="neutral" also, and all this solved the problem.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGeorge MauerView Question on Stackoverflow
Solution 1 - asp.netGeorge MauerView Answer on Stackoverflow
Solution 2 - asp.netdmatsonView Answer on Stackoverflow
Solution 3 - asp.netTuanDPHView Answer on Stackoverflow
Solution 4 - asp.netusefulBeeView Answer on Stackoverflow
Solution 5 - asp.netNick JonesView Answer on Stackoverflow
Solution 6 - asp.netHemslingoView Answer on Stackoverflow
Solution 7 - asp.netNaroView Answer on Stackoverflow