Представление на основе Razor не видит сборки, на которые имеются ссылки

101

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

@model MyClasses.MyModel

приводит к ошибке в Visual Studio 2010: « MyClassesНе удалось найти тип или имя пространства имен (вам не хватает директивы using или ссылки на сборку?)».

Тот же класс, на который есть ссылка в стандартном механизме представления, работает нормально. У меня такая же проблема, пытаясь ссылаться на класс в теле моего представления.

Мне что-то не хватает в Razor или мне нужно как-то ссылаться на сборку?

Nickwesselman
источник
Вы используете все пространство имен? @model namespace.myclasses.mymodel, может быть?
Brettski

Ответы:

107

Существует новый раздел конфигурации, который используется для ссылки на пространства имен для представлений Razor.

Откройте web.configфайл в своей Viewsпапке и убедитесь, что в нем есть следующее:

<configuration>
    <configSections>
        <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
            <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
            <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=1.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=3.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.Routing" />
                <add namespace="SquishIt.Framework" />
                <add namespace="Your.Namespace.Etc" />
            </namespaces>
        </pages>
    </system.web.webPages.razor>
</configuration>

В качестве альтернативы вы можете добавить операторы using в общий макет:

@using Your.Namespace.Etc;
<!DOCTYPE html>
<head>
....

После редактирования Web.config перезапустите Visual Studio, чтобы изменения вступили в силу.

Quentin-Starin
источник
18
Это работает, однако убедитесь , что ваши сборки с привязкой Copy Local = true. В противном случае внешние сборки могут не работать.
Терри
1
Здесь следует отметить, что если вы используете представления из «виртуального» источника (такого как БД) вместо использования файлов реального представления, вы должны поместить это в файл ROOT web.config, чтобы код в представлениях работал.
NightOwl888
2
@Terry, похоже, что Copy local = true необходимо даже для некоторых сборок с корневым пространством имен System.
Дэн Эспарза
2
Мои сборки загружаются во время выполнения, поэтому я не могу использовать файл web.config для их добавления. Что еще я могу попробовать? Есть ли способ импортировать мои внешние представления с их собственными файлами web.config? Это довольно странно, потому что я ссылаюсь на пространства имен в той же сборке, что и мои представления.
Максим Ви.
Перезапуск Visual Studio не требуется. Достаточно просто закрыть и снова открыть просмотры.
user247702 09
58

У меня была такая же проблема: MVC3 Project MyCore.Web ссылался на пространство имен MyCore.DBLayer из другого проекта в том же решении (с именем сборки MyCoreDBLayer). Все объекты из MyCore.DBLayer отлично работали в контроллерах и моделях, но не выполнялись в представлениях Razor с ошибкой «Тип или имя пространства имен« DBLayer »не существует в пространстве имен« MyCore »(отсутствует ли ссылка на сборку?)», Которая была явно не так.

  • Для параметра «Копировать локально» задано значение true.
  • Добавление операторов using ... в представления Razor было бесполезным
  • Добавление пространств имен в раздел system.web.webPages.razor тоже было бесполезным

Добавление ссылки на сборку в раздел system.web / compilation / assemblies корневого файла web.config устранило проблему. Теперь раздел выглядит так:

<system.web>
    <compilation debug="true" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        **<add assembly="MyCoreDBLayer" />**
      </assemblies>
    </compilation>
...
</system.web>

Пропуск версии, культуры и токена пока допустим, но в будущем это будет исправлено.

VB
источник
Это решение работает, но это плохая идея. Когда я сделал все свои классы внутренними и сделал веб-сборку другом MyCoreDBLayer, он перестал работать. В итоге я написал общедоступные классы как модель MVC, которая охватывает мои классы из дружественных сборок. Я считаю, что не следует использовать классы, отличные от классов из пространства имен моделей MVC в представлениях Razor - всегда можно написать оболочку
VB
Это сработало для меня, я попытался добавить его в, Views/web.configи он работал, когда он был помещен туда.
guanome 02
18

В моем случае отдельный проект, содержащий пространство имен, был консольным приложением. Изменение его на библиотеку классов устранило проблему.

Сэм
источник
1
Это решило проблему для меня. Сначала я попытался создать библиотеку классов (пакет), но столкнулся с проблемами, связанными с нужным мне пакетом nuget. Лучше не фантазировать и просто создать базовую библиотеку классов (DLL)
redwards510
15

Ничего из вышеперечисленного у меня тоже не помогло;

  • DLL были настроены на Копирование локального
  • Добавление пространств имен в оба файла web.configs ничего не дало
  • Добавление ссылок на сборки в system.web \ compilation \ assemblies тоже не помогло (хотя я не удалял эти ссылки, так что может быть, они тоже нужны)

Но я наконец нашел то, что сработало для меня:

Это произошло потому, что мои выходные данные сборки были отправлены в bin \ Debug \ для конфигурации отладки и bin \ Release \ для конфигураций Release. Как только я изменил конфигурацию сборки на "bin \" для всех конфигураций (как показано на изображении ниже), все стало работать как надо !!!

Конфигурация сборки

Я понятия не имею, почему разделение ваших сборок по папкам Release и Debug должно приводить к нарушению синтаксиса Razor, но, похоже, это связано с тем, что что-то не может найти сборки. Для меня проекты, в которых были проблемы с синтаксисом бритвы, на самом деле являются моими проектами «библиотеки бритвы». Они заданы как проекты приложений, однако я использую их как библиотеки классов с RazorGenerator для компиляции своих представлений. Когда я действительно попытался запустить один из этих проектов напрямую, это вызвало следующую ошибку конфигурации:

Не удалось загрузить файл или сборку System.Web.Helpers, Version = 3.0.0.0, Culture = нейтральный, PublicKeyToken = 31bf3856ad364e35 или одну из ее зависимостей. Система не может найти указанный файл.

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

Сильвия
источник
1
Кстати, подтвердили, что вам не нужен раздел system.web \ compilation \ сборок, если библиотеки DLL находятся непосредственно в папке bin. Это может вернуться к тому, что будет просто <compilation debug = "true" targetFramework = "4.5.1" />
Сильвия
2
Святая корова! После долгого поиска решения это наконец решило мои представления Razor в проекте библиотеки классов !! Огромное спасибо.
Hullah
2
Невероятно! Я собирал свою библиотеку представлений классов в каталог другого проекта и столкнулся с этой проблемой. Путь сборки должен быть bin \, чтобы это работало. Теперь вместо этого используется post build xcopy.
GlacialSpoon
1
Я использую Razor Engine в проекте библиотеки классов и столкнулся с той же проблемой. Установка пути вывода на "bin \" решила и для меня эту проблему. Как и GlacialSpoon, я копирую сборку на этапе после сборки в правильную папку вывода. Не лучший способ, но, по крайней мере, работает Intellisense, ссылки на сборки и подсветка синтаксиса.
Octoate
Стоит отметить, что исходная проблема возникает, если ваш пользовательский выходной каталог указывает на родительский каталог ala '.. \ some \ dir \'. Но если вы измените выходной каталог, чтобы сказать «some \ dir \», все будет работать нормально. Это точно дьявольский глюк в матрице.
XDS
7

Кажется, вы ищете этот ответ: https://stackoverflow.com/a/4136773/176877

То есть откройте внутренний Views \ Web.Config (НЕ корневой) и добавьте пространство имен под тегом Pages:

<system.web.webPages.razor>
  <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory.../>
  <pages pageBaseType="System.Web.Mvc.WebViewPage">
    <namespaces>
      <add namespace="System.Web.Mvc" />
      ...
      <add namespace="System.Web.Routing" />
      <!-- Your namespace here -->
    </namespaces>

Сохраните это, затем закройте и снова откройте файл Razor.

Если вы используете области, вам необходимо сделать это для каждого Web.Config в каждой области.

Visual Studio с годами стала более сложной, поэтому может потребоваться закрыть файл Razor, выполняющий сборку отладки, а затем повторно открыть файл Razor, или, в худшем случае, потребуется перезапустить Visual Studio. Но в конечном итоге он представит вам файл Razor, как если бы все в этом списке пространств имен было в операторах @using в верхней части всех ваших представлений.

Крис Москини
источник
4

В ASP.NET Core MVC решение состоит в том, чтобы добавить usingфайл _ViewImports.cshtml вместо того, чтобы помещать его web.config в папку View при работе с ASP.NET MVC 5.

_ViewImports.cshtml

@using mySolution
@using mySolution.ViewModels // <-- Add this, and place your ViewModel (e.g. LoginViewModel) in here.
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Посмотреть

@model LoginViewModel // Add to _ViewImports to make this line work
<div>This is the View for the login screen.</div>
Radbyx
источник
3

Что касается меня, я ссылался на проект, который был консольным приложением. Он был настроен на сборку как exe (консольное приложение) вместо библиотеки классов (DLL). Когда я изменил это, я смог без проблем видеть модели из этого отдельного проекта.

user1619480
источник
Спасибо @ user1619480, у меня была такая же проблема, и в моем случае из библиотеки классов .Net Framework я добавил с помощью VS 2017, и по какой-то причине типом вывода было консольное приложение.
danfer
1

Я получал ту же ошибку при попытке использовать объекты Smo в представлении Razor. По-видимому, это связано с тем, что Razor не может найти библиотеки DLL, на которые есть ссылки в проекте. Я решил эту проблему, установив для параметра «Копировать локально» значение true для всех библиотек Smo, однако может быть лучшее решение (см. Ссылку Czechdude выше). Редактирование @using и web.config бесполезно, потому что они нужны только в том случае, если вы хотите опустить пространство имен часть из имен типов (например, Server вместо Microsoft.SqlServer.Management.Smo.Server)

Зар Шардан
источник
1

Я получал аналогичную ошибку после переноса моей машины разработчика с Win7 32bit на Win7 64bit. Сообщение об ошибке:

...\Web\Views\Login.cshtml: ASP.net runtime error: [A]System.Web.WebPages.Razor.Configuration.HostSection cannot be cast to [B]System.Web.WebPages.Razor.Configuration.HostSection. Type A originates from System.Web.WebPages.Razor, Version=1.0.0.0 ... Type B originates from ... Version=2.0.0.0

Оказывается, у меня были обе версии в GAC. Представление web.configссылалось на v1, но приложение ссылалось на v2. Удалены упомянутые сборки и повторно добавлена ​​версия v1. оф System.Web.WebPages.Razorи др.

Тим
источник
+1 спасибо, это был мой последний пункт, теперь я могу отлаживать asp.net mvc 4 hohoho!
citykid
1

ну, для меня все было иначе. Мне не хватало сборки моего проекта консольного приложения с проектом MVC. Итак, добавления ссылки было недостаточно.

ну, это может помочь кому-то другому. перейдите в корневой файл web.config system.web-> compilation-> добавьте ссылку на свой проект следующим образом.

<assemblies> <add assembly="Your.Namespace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/> </assemblies>

Джаванд Сингх
источник
1

У меня тоже была такая же проблема, но проблема была в целевой структуре сборки .

Указанная сборка находилась в .NET Framework 4.6, где для проекта задано .NET framework 4.5.

Надеюсь, это поможет тому, кто напортачил с фреймворками.

Geeganage
источник
1

Имя вашей ПАПКИ проекта должно быть таким же. Если имя вашего проекта или решения отличается, MVC причинит вам вред.

Пример: если вы создаете новое приложение, и оно получает имя по умолчанию Webapplicaiton1, то это пространство имен будет создано. Итак, позвольте нам сказать, что вы не хотите иметь это пространство имен, поэтому из VS вы меняете везде, где видите, на «MyNamespace». Вы также выполните поиск и замените весь код из «Webapplication1» и замените его на «MyNamespace». Это также изменяет файл web.config, так что он включает

Теперь все будет работать, кроме представлений Razor.

RazorViews не может его найти, потому что есть какая-то странная зависимость от FOLDERNAME проекта. Ужасный дизайн.

Я проверил это частично, скопировав свои файлы в новое решение, и единственное отличие - это имя папки.

Йенс Тандстад
источник
Невероятно, как это смешно! Я переименовал имя папки проекта в правое, открыл решение в текстовом файле и исправил описание папки! Это сработало! Я использую визуальную студию 2019
Даниэль
0

Попробуйте добавить пространство имен, в котором вы MyClassesнаходитесь, в web.config в разделе

<pages> <namespaces></namespaces> </pages>

Амурра
источник
0

включить все пространство имен

@model namespace.myclasses.mymodel
Бреттски
источник
0

Ни один из этих https://stackoverflow.com/a/7597360/808128 не работает для меня. Даже «добавление ссылки на сборку в раздел system.web / compilation / assemblies корневого файла web.config». Таким образом, у меня остается два пути: 1) добавить общедоступный класс оболочки для моей сборки, чтобы код Razor мог получить доступ к этой сборке через эту оболочку; 2) просто добавьте логику сборки к общедоступному классу в той же сборке, где находится код Razor.

user808128
источник
0

Помимо внесения изменений в web.config для <assemblies>и<namespaces> , я обнаружил, что сборка GAC имеет большое значение. Вы можете применить токен культуры и открытого ключа, как любую базовую сборку .NET, зарегистрированную глобально.

Некоторые могут вздрогнуть при упоминании GAC. Но как разработчик BizTalk я вырос, чтобы принять это.

Метки
источник
0

Это решение сработало для меня (это забавно, но работает)

Я отредактировал страницы просмотра, скопировал содержимое и вставил в него, я не изменил никакого содержимого представлений, а просто отредактировал, чтобы визуальная студия могла отслеживать страницы, и после этого все начало работать

Решение - просто отредактируйте страницы и замените их такими же (сработало для меня)

Арун Прасад ES
источник
0

в моделях spacename yourClassModel добавьте public перед именем class

public class yourClassModel{
    prop
}
Милад Джафари
источник
0

В моем случае пакет, который я пытался использовать, ссылался на стандарт .net 2.1, в то время как мой проект библиотеки классов бритвы был установлен на 2.0

Денис Райхельт
источник