La vista basada en Razor no ve ensamblados referenciados

101

Estoy intentando crear una vista fuertemente tipada basada en una clase de otro ensamblado. Sin embargo, por alguna razón, mi vista de Razor no parece tener ninguna visibilidad de otros ensamblados a los que se hace referencia en mi proyecto. p.ej

@model MyClasses.MyModel

da como resultado el error en Visual Studio 2010, "No se MyClassespudo encontrar el tipo o el nombre del espacio de nombres (¿falta una directiva using o una referencia de ensamblado?)".

La misma clase a la que se hace referencia en el motor de vista estándar funciona bien. Tengo el mismo problema al intentar hacer referencia a la clase en el cuerpo de mi vista.

¿Me falta algo sobre Razor o necesito hacer referencia al ensamblado de alguna otra manera?

Nickwesselman
fuente
¿Estás usando todo el espacio de nombres? @model namespace.myclasses.mymodel, ¿quizás?
Brettski

Respuestas:

107

Hay una nueva sección de configuración que se usa para hacer referencia a los espacios de nombres para las vistas de Razor.

Abra el web.configarchivo en su Viewscarpeta y asegúrese de que tenga lo siguiente:

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

Alternativamente, puede agregar declaraciones using a su diseño compartido:

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

Después de editar Web.config, reinicie Visual Studio para aplicar los cambios.

quentin-starin
fuente
18
Esto funciona, sin embargo, asegúrese de que se haga referencia a sus ensamblajes Copy Local = true. Es posible que los ensamblajes externos no funcionen de otra manera.
Terry
1
Cabe señalar aquí que si está utilizando vistas de una fuente "virtual" (como la base de datos) en lugar de utilizar archivos de vistas reales, debe poner esto en el archivo ROOT web.config para que funcione el código de las vistas.
NightOwl888
2
@Terry, parece que Copy local = true es necesario incluso para algunos ensamblados con espacio de nombres de raíz del sistema.
Dan Esparza
2
Mis ensamblados se cargan en tiempo de ejecución, por lo que no puedo usar el archivo web.config para agregarlos. ¿Hay algo más que pueda probar? ¿Hay alguna forma de importar mis vistas externas con sus propios archivos web.config? Es bastante extraño porque estoy haciendo referencia a espacios de nombres dentro del mismo ensamblado que mis vistas.
Maksim Vi.
No es necesario reiniciar Visual Studio. Basta con cerrar y volver a abrir las Vistas.
user247702
58

Tuve el mismo problema: MVC3 Project MyCore.Web hacía referencia al espacio de nombres MyCore.DBLayer de otro proyecto en la misma solución (con el nombre de ensamblado MyCoreDBLayer). Todos los objetos de MyCore.DBLayer funcionaron perfectamente en controladores y modelos, pero fallaron en las vistas de Razor con un error 'El tipo o nombre del espacio de nombres' DBLayer 'no existe en el espacio de nombres' MyCore '(¿le falta una referencia de ensamblaje?)' Que era obviamente no es el caso.

  • La opción Copiar local se estableció en verdadera.
  • Agregar declaraciones "usando ..." en las vistas de Razor fue inútil
  • Agregar espacios de nombres a la sección system.web.webPages.razor también fue inútil

Agregar referencia de ensamblaje a la sección system.web / compilation / ensambles del archivo raíz web.config solucionó el problema. La sección ahora se ve así:

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

Omitir versión, cultura, token estaba bien por ahora, pero debería arreglarse en el futuro.

VB
fuente
Esta solución funciona pero es una mala idea. Cuando hice todas mis clases internas e hice que el ensamblaje web fuera un amigo de MyCoreDBLayer, dejó de funcionar. Terminé escribiendo clases públicas como un modelo MVC que envuelve mis clases de ensamblajes de amigos. Creo que no se deben usar clases que no sean del espacio de nombres de modelos de MVC en las vistas de Razor; siempre es posible escribir un contenedor
VB
Esto funcionó para mí, intenté agregarlo Views/web.configy funcionó cuando se colocó allí también.
guanome
18

En mi caso, el proyecto separado que contenía el espacio de nombres era una aplicación de consola. Cambiarlo a una biblioteca de clases solucionó el problema.

Sam
fuente
1
Esto me lo resolvió. Primero intenté hacer una biblioteca de clases (paquete), pero encontré problemas al hacer referencia a un paquete nuget que necesitaba. Es mejor no ser sofisticado y simplemente hacer una biblioteca de clases básica (DLL)
redwards510
15

Ninguno de los anteriores funcionó para mí tampoco;

  • Dlls se establecieron para copiar local
  • Agregar espacios de nombres a ambos web.configs no hizo nada
  • Agregar referencias de ensamblado a system.web \ compilation \ ensambles tampoco ayudó (aunque no he eliminado estas referencias, por lo que puede ser que también sean necesarias)

Pero finalmente encontré algo que funcionó para mí:

Fue porque tenía mi Salida de compilación yendo a bin \ Debug \ para configuración de depuración y bin \ Release \ para configuraciones de versión. Tan pronto como cambié la configuración de compilación a "bin \" para todas las configuraciones (según la imagen a continuación), ¡todo comenzó a funcionar como debería!

Construir configuración

No tengo idea de por qué la separación de sus compilaciones en las carpetas Release y Debug debería hacer que la sintaxis de Razor se rompa, pero parece ser porque algo no pudo encontrar los ensamblados. Para mí, los proyectos que tenían problemas de sintaxis de afeitar son en realidad mis proyectos de 'biblioteca de afeitar'. Están configurados como proyectos de aplicación, sin embargo, los uso como bibliotecas de clases con RazorGenerator para compilar mis vistas. Cuando intenté ejecutar uno de estos proyectos directamente, causó el siguiente error de configuración:

No se pudo cargar el archivo o ensamblado 'System.Web.Helpers, Version = 3.0.0.0, Culture = neutral, PublicKeyToken = 31bf3856ad364e35' o una de sus dependencias. El sistema no puede encontrar el archivo especificado.

Esto me llevó a intentar cambiar la salida de la compilación, ya que me di cuenta de que para todos los proyectos web la salida de la compilación parece estar siempre directamente en la carpeta bin, a diferencia de la predeterminada para las bibliotecas de clases, que tienen carpetas de liberación y depuración.

Sylvia
fuente
1
Por cierto, he confirmado que no es necesario tener la sección system.web \ compilation \ assemblies una vez que los dlls estén directamente en la carpeta bin. Esto puede volver a ser simplemente <compilation debug = "true" targetFramework = "4.5.1" />
Sylvia
2
¡Santo cielo! Después de mucho tiempo buscando una solución, ¡esto finalmente resolvió mis vistas de Razor en un proyecto de biblioteca de clases! Muchas gracias.
Hullah
2
¡Increíble! Estaba construyendo mi biblioteca de vistas de clase en el directorio de otro proyecto y tuve este problema. La ruta de construcción debe ser bin \ para que esto funcione. Ahora usando post build xcopy en su lugar.
GlacialSpoon
1
Estoy usando Razor Engine en un proyecto de biblioteca de clases y enfrenté el mismo problema. Establecer la ruta de salida en "bin \" también me resolvió este problema. Al igual que GlacialSpoon, copio el ensamblaje en un paso posterior a la compilación en la carpeta de salida correcta. No es la mejor manera, pero al menos, Intellisense, ensamblajes de referencia y resaltado de sintaxis funciona.
octoato
Vale la pena señalar que el problema original surge si su directorio de salida personalizado apunta a un directorio padre ala '.. \ some \ dir \'. Pero si cambia el directorio de salida para decir 'algún \ dir \', entonces todo funciona bien. Este es un error diabólico en la matriz, seguro.
XDS
7

Parece que está buscando esta respuesta: https://stackoverflow.com/a/4136773/176877

Es decir, abra el Views \ Web.Config interno (NO el raíz) y agregue el espacio de nombres debajo de la etiqueta 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>

Guárdelo, luego cierre y vuelva a abrir el archivo Razor.

Si está utilizando Áreas, deberá hacer esto para cada Web.Config en cada Área.

Visual Studio se ha vuelto más problemático a lo largo de los años, por lo que puede requerir cerrar el archivo Razor ejecutando una compilación de depuración y luego volver a abrir el archivo Razor, o en el peor de los casos, puede requerir reiniciar Visual Studio. Pero en última instancia, le presentará el archivo Razor como si todo en esa lista de espacios de nombres estuviera en declaraciones @using en la parte superior de todas sus Vistas.

Chris Moschini
fuente
4

En ASP.NET Core MVC, la solución es agregar un usingen _ViewImports.cshtml, en lugar de ponerlo web.config en la carpeta Ver cuando se trabaja con 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

Ver

@model LoginViewModel // Add to _ViewImports to make this line work
<div>This is the View for the login screen.</div>
radbyx
fuente
3

Para mí, estaba haciendo referencia a un proyecto que era una aplicación de consola. Se configuró para compilarse como un exe (aplicación de consola) en lugar de una biblioteca de clases (DLL). Cuando cambié esto, pude ver los modelos de ese proyecto separado sin problemas.

user1619480
fuente
Gracias @ user1619480, tuve el mismo problema y, en mi caso, desde una biblioteca de clases de .Net Framework que agregué usando VS 2017 y, por alguna razón, el tipo de salida fue la aplicación de consola.
danfer
1

Recibí el mismo error al intentar usar objetos Smo en una vista de Razor. Aparentemente, esto se debe a que Razor no puede encontrar las DLL a las que se hace referencia en el proyecto. Resolví esto estableciendo "Copiar local" en verdadero para todos los dlls de Smo, sin embargo, podría haber una mejor solución (ver el enlace de Czechdude arriba) @using y las ediciones web.config son inútiles porque solo son necesarias si desea omitir el espacio de nombres parte de los nombres de los tipos (por ejemplo, Server en lugar de Microsoft.SqlServer.Management.Smo.Server)

Zar Shardan
fuente
1

Recibí un error similar después de mover mi máquina de desarrollo de Win7 32bit a Win7 64bit. Mensaje de error:

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

Resulta que tenía ambas versiones en el GAC. La vista hacía web.configreferencia a v1, pero la aplicación hacía referencia a v2. Se eliminaron los ensamblados a los que se hace referencia y se volvió a agregar v1. de System.Web.WebPages.Razor, etc.

Tim
fuente
+1 gracias, este fue mi punto final, ahora puedo depurar asp.net mvc 4 ¡hohoho!
citykid
1

bueno, para mi fue diferente. Faltaba el ensamblaje de mi proyecto de aplicación de consola con el proyecto MVC. Entonces, agregar una referencia no fue suficiente.

bueno, esto podría ayudar a alguien más. vaya al archivo raíz web.config system.web-> compilation-> agregue la referencia de su proyecto de esta manera.

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

Jawand Singh
fuente
1

También tuve el mismo problema, pero el problema estaba en el marco de Target del ensamblaje .

El ensamblado al que se hace referencia estaba en .NET Framework 4.6, donde el proyecto se configuró en .NET Framework 4.5.

Espero que esto ayude a alguien que se haya equivocado con los marcos.

Geeganage
fuente
1

El nombre de la CARPETA del proyecto debe ser el mismo. Si el nombre de su proyecto o solución es diferente, MVC lo perjudicará.

Ejemplo: si crea una nueva aplicación y obtiene el nombre predeterminado Webapplicaiton1, se creará este espacio de nombres. Por lo tanto, digamos que no desea tener este espacio de nombres, por lo que desde el VS cambia todos los lugares que pueda ver a "MyNamespace". También busca y reemplaza todo el código de "Webapplication1" y lo reemplaza con "MyNamespace". Esto también cambia el archivo web.config, para que incluya

Ahora todo funcionará, excepto las vistas de Razor.

RazorViews no puede encontrarlo, porque existe algún tipo de dependencia extraña en el FOLDERNAME del proyecto. Es un diseño terrible.

He probado esto semi-a fondo copiando mis archivos en una nueva solución, y la única diferencia es el nombre de la carpeta.

Jens Tand
fuente
¡Increíble lo ridículo que es esto! ¡Cambié el nombre de la carpeta del proyecto, a la derecha, y abrí la solución en un archivo de texto y corrigí la descripción de la carpeta! ¡Funcionó! Estoy usando Visual Studio 2019
Daniel
0

Intente agregar el espacio de nombres en el que se MyClassesencuentra en web.config en

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

amurra
fuente
0

incluir todo el espacio de nombres

@model namespace.myclasses.mymodel
Brettski
fuente
0

Ninguno de estos https://stackoverflow.com/a/7597360/808128 funciona para mí. Incluso "agregar referencia de ensamblaje a la sección system.web / compilation / ensambles del archivo raíz web.config". Así que las dos formas me quedan: 1) agregar una clase de envoltura pública para mi ensamblado a la que el código de Razor pueda acceder a este ensamblado a través de esta envoltura; 2) simplemente agregue lógica de ensamblaje a una clase pública en el mismo ensamblado donde se encuentra el código de Razor.

user808128
fuente
0

Además de hacer los cambios de web.config para <assemblies>y <namespaces>, descubrí que GAC'ing el ensamblado hizo una gran diferencia. Puede aplicar la cultura y el token de clave pública como cualquier ensamblado principal de .NET que esté registrado globalmente.

Algunos pueden estremecerse ante la mención del GAC. Pero como desarrollador de BizTalk, he llegado a adoptarlo.

Marcas
fuente
0

Esta solución funcionó para mí (es gracioso, pero funciona)

Edité las páginas de la vista, copié el contenido y lo pegué, no cambié ningún contenido de las vistas, solo las edité para que Visual Studio pudiera hacer lo necesario para rastrear las páginas, y luego todo comenzó a funcionar.

Solución: simplemente edite las páginas y reemplácelas con las mismas páginas (funcionó para mí)

Arun Prasad ES
fuente
0

en modelos de nombre de espacio, yourClassModel, agregue público antes de la clase de nombre

public class yourClassModel{
    prop
}
Milad Jafari
fuente
0

En mi caso, el paquete que intenté usar hacía referencia al estándar 2.1 de .net, mientras que mi proyecto de biblioteca de clases de afeitar estaba configurado en 2.0

Denis Reichelt
fuente