После обновления Windows "Тип или имя пространства имен" Html "не существует в пространстве имен" System.Web.Mvc ""

Я сделал обновление Windows, и после этого мое приложение asp.net mvc 5 больше не будет загружать жалобы на

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

указывающий мои взгляды на ошибку web.config

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

Теперь это очень запутанно. В моем проекте я вижу пространство имен Html, открывая мою сборку в ILSpy. Я могу перейти к границе System.Web.Mvc, и я тоже могу это сделать, а журнал слияния не показывает никаких подозрительных ошибок привязки.

Как будто мои взгляды привязываются (успешно) к старой версии Mvc. Почему это когда-нибудь произойдет? Как я могу это исправить?

Позвольте мне пояснить, что никаких изменений конфигурации и даже изменений кода не было. Это все на моей машине dev на IISExpress. Он был запущен, я сделал обновление и перезагрузился, и теперь он больше не работает.

Вот мои последние установки из обновления. Я мог бы начать их удаление один за другим, но я хочу знать, что на самом деле происходит неправильно, поскольку мне кажется, что я пропускаю часть истории.

Installs from the update

Ответ 1

Святое дерьмо, благодаря @Nevada-Williford за намек. Вступив и установив ссылку System.Web.Mvc на <Private>True</Private> (Копировать локально = True), исправил ее. Обратите внимание, что перед обновлением все работало, после обновления мне пришлось изменить мой csproj, чтобы он снова работал.

Рабочая теория о том, что происходит:

Copy Local = True и <Private>True</Private> использовался почти, но не совсем, то же самое. Первая была установкой Visual Studio, вторая - установкой msbuild, Если параметр msbuild отсутствовал, будет применена установка Visual Studio (если вы были в VS). В этом обновлении я думаю, что они изменили его, поэтому Copy Local просто отражает атрибут присутствия.

В нашем проекте у нас нет этого атрибута, явно установленного, но Copy Local = True, поэтому до обновления System.Web.Mvc.dll копируется в каталог bin. После обновления, поскольку атрибут отсутствует Copy Local показывает False, и вы должны установить его в True, чтобы убедиться, что вы получили локальную копию.

Вручную установка Copy Local = True (или добавление этого элемента xml в msbuild) устраняет проблему.

Изменить: Пока это ответ на конкретный вопрос, любой, кто придет сюда, должен прочитать комментарий и другие ответы - особенно dmatson - для большего количества контекста, оговорок и связанных с ними ошибок.

Ответ 2

Это было нарушено для всех пользователей без CopyLocal=true (или в MSBuild говорить, <Private>True</Private>) MS14-059. Шаблоны MVC устанавливают по умолчанию <Private>True</Private>, но если вы используете NuGet для обновления версии MVC, вы теряете этот параметр (см. Ошибка NuGet # 4344).

Есть два аспекта проблемы:

  • Razor не включает ссылку на MVC по умолчанию, поэтому его компиляция не будет работать, если в вашей папке bin не будет использована какая-либо версия MVC DLL.
  • Если вы развернетесь на отдельный компьютер, на котором этого обновления не установлено, MVC DLL больше не входит в ваш вывод, поэтому MVC будет отсутствовать.

Вы видите проблему №1. Чтобы решить обе проблемы, я рекомендую сделать следующие изменения:

  • Добавьте следующую конфигурацию в 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>
    
  • Задайте CopyLocal=true в пользовательском интерфейсе VS для ссылки на проект или вручную добавьте следующую строку ниже в Reference в файле .csproj:

    <Private>True</Private>
    

Итак, ваша полная ссылка должна выглядеть примерно так:

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

Обратите внимание, что NuGet удалит параметр CopyLocal/Private, если вы снова обновите пакеты в будущем. (Например, если вы сегодня обновляетесь до MVC 5.2). Если эта версия MVC когда-либо была GAC'd, проблема № 1 выше не будет повторяться до тех пор, пока вы добавили конфигурацию на шаге A выше, но проблема №2 все еще может повториться. Чтобы этого не произошло в будущем, я бы рекомендовал вручную установить CopyLocal обратно в true при каждом обновлении пакета NuGet.

Ответ 3

  • Вы можете перейти к ссылкам на текущий проект.
  • Щелкните правой кнопкой мыши в dll System.Web.Mvc и выберите "Свойства"
  • Откроется окно "Свойства"
  • Измените Скопировать локальную на True

Ответ 4

Настройка CopyLocal = true не помогла. Очистка раствора, затем его закрытие и повторное открытие снова. Возможно, вам придется закрыть весь экземпляр Visual Studio.

Ответ 5

Это, по-видимому, вызвано обновлением Windows (KB2990942), чтобы устранить уязвимость безопасности MS14-059, позволяя обходить функцию безопасности. Наши сборки перестали работать на нашем сервере сборки после установки Windows Update, и обновление файлов csproj для использования 4.0.0.1 для ссылки System.Web.Mvc устранило проблему.

Описание уязвимости Microsoft:

Уязвимость может привести к обходу функции безопасности, если злоумышленник убедит пользователя щелкнуть ссылку специально созданного или посетить веб-страницу, содержащую специально созданный контент, предназначенный для использования этой уязвимости. В сценарии атаки через Интернет злоумышленник может разместить специально созданный веб-сайт, предназначенный для использования этой уязвимости через веб-браузер, а затем убедить пользователя просмотреть веб-сайт. Злоумышленник также может воспользоваться уязвимыми веб-сайтами и веб-сайтами, которые принимают или размещают контент или рекламу, предоставленную пользователем. Эти веб-сайты могут содержать специально созданный контент, который может использовать уязвимость. Однако во всех случаях злоумышленник не сможет заставить пользователей просматривать контент, контролируемый атакующим. Вместо этого злоумышленнику придется убедить пользователей принять меры, как правило, путем нажатия на ссылку в сообщении электронной почты или в сообщении Instant Messenger, которое отправляет их на сайт злоумышленника, или путем открытия их вложения, отправленного по электронной почте.

Ответ 6

Как и установка CopyLocal = true в ссылке на проект, вам также может потребоваться изменить файл Web.Config таким образом...

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

Обратите внимание на newVersion = "4.0.0.1". Это сработало для меня, и я надеюсь, что это поможет и нескольким людям.

Сохраняет обновление структуры MVC на любых тестовых/производственных серверах.

Приветствует Microsoft. Ты лучший!

Ваша попытка заставить меня выглядеть некомпетентно перед моими клиентами снова сорвана!

Ответ 7

Как и установка CopyLocal=true в ссылке на проект, вам также может потребоваться изменить файл Web.Config, например, так...

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

Я добавил culture="neutral", и все это решило проблему.