La vue basée sur Razor ne voit pas les assemblys référencés

101

J'essaie de créer une vue fortement typée basée sur une classe d'un autre assemblage. Pour une raison quelconque, ma vue Razor ne semble pas avoir de visibilité sur les autres assemblys référencés dans mon projet. par exemple

@model MyClasses.MyModel

entraîne l'erreur dans Visual Studio 2010, «Le type ou le nom de l'espace de noms MyClassesest introuvable (vous manque une directive using ou une référence d'assembly?)».

La même classe référencée dans le moteur de vue standard fonctionne correctement. J'ai le même problème en essayant de référencer la classe dans le corps de ma vision.

Est-ce que je manque quelque chose à propos de Razor ou dois-je référencer l'assemblage d'une autre manière?

Nickwesselman
la source
Utilisez-vous tout l'espace de noms? @model namespace.myclasses.mymodel, peut-être?
Brettski

Réponses:

107

Une nouvelle section de configuration est utilisée pour référencer les espaces de noms pour les vues Razor.

Ouvrez le web.configfichier dans votre Viewsdossier et assurez-vous qu'il contient les éléments suivants:

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

Vous pouvez également ajouter des instructions using à votre mise en page partagée:

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

Après avoir modifié le Web.config, redémarrez Visual Studio pour appliquer les modifications.

quentin-starin
la source
18
Cela fonctionne, mais assurez-vous que vos assemblys sont référencés avec Copy Local = true. Les assemblages externes peuvent ne pas fonctionner autrement.
Terry
1
Il convient de noter ici que si vous utilisez des vues d'une source "virtuelle" (telle que la base de données) au lieu d'utiliser des fichiers de vues réels, vous devez placer ceci dans le fichier web.config ROOT pour que le code des vues fonctionne.
NightOwl888
2
@Terry, il semble que Copy local = true soit nécessaire même pour certains assemblys d'espacement de noms de racine système.
Dan Esparza
2
Mes assemblys sont chargés au moment de l'exécution, je ne peux donc pas utiliser le fichier web.config pour les ajouter. Y a-t-il autre chose que je puisse essayer? Existe-t-il un moyen d'importer mes vues externes avec leurs propres fichiers web.config? C'est plutôt étrange car je référence des espaces de noms dans le même assemblage que mes vues.
Maksim Vi.
Le redémarrage de Visual Studio n'est pas nécessaire. Il suffit de fermer et de rouvrir les vues.
user247702
58

J'ai eu le même problème: MVC3 Project MyCore.Web faisait référence à l'espace de noms MyCore.DBLayer d'un autre projet dans la même solution (avec le nom d'assembly MyCoreDBLayer). Tous les objets de MyCore.DBLayer fonctionnaient parfaitement dans les contrôleurs et les modèles mais échouaient dans les vues Razor avec une erreur `` Le type ou le nom d'espace de noms 'DBLayer' 'n'existe pas dans l'espace de noms' MyCore '(vous manquez une référence d'assemblage?)' Qui était évidemment pas le cas.

  • L'option Copier local a été définie sur true.
  • L'ajout d'instructions "using ..." dans les vues Razor était inutile
  • L'ajout d'espaces de noms à la section system.web.webPages.razor était également inutile

L'ajout de l'assembly referecene à la section system.web / compilation / assemblies du fichier racine web.config a résolu le problème. La section ressemble maintenant à:

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

Omettre la version, la culture et le jeton était acceptable pour le moment, mais devrait être corrigé à l'avenir.

VB
la source
Cette solution fonctionne mais c'est une mauvaise idée. Quand j'ai rendu toutes mes classes internes et fait de l'assemblage Web un ami de MyCoreDBLayer, cela a cessé de fonctionner. J'ai fini par écrire des classes publiques en tant que modèle MVC qui entourent mes classes à partir d'assemblies d'amis. Je pense qu'il ne faut pas utiliser d'autres classes que celles de l'espace de noms des modèles de MVC dans les vues Razor - il est toujours possible d'écrire un wrapper
VB
Cela a fonctionné pour moi, j'ai essayé de l'ajouter au Views/web.configet cela a fonctionné quand il a été placé là aussi.
guanome le
18

Dans mon cas, le projet séparé qui contenait l'espace de noms était une application console. Le changer en une bibliothèque de classes a résolu le problème.

Sam
la source
1
Cela a résolu le problème pour moi. J'ai d'abord essayé de créer une bibliothèque de classes (package), mais j'ai rencontré des problèmes pour référencer un package nuget dont j'avais besoin. Mieux
vaut
15

Aucun de ces éléments n'a fonctionné pour moi non plus;

  • Les DLL ont été définies sur Copier local
  • L'ajout d'espaces de noms aux deux web.configs n'a rien fait
  • L'ajout de références d'assembly à system.web \ compilation \ assemblies n'a pas non plus aidé (bien que je n'ai pas supprimé ces références, il se peut donc qu'elles soient également nécessaires)

Mais j'ai finalement trouvé quelque chose qui a fonctionné pour moi:

C'était parce que ma sortie de construction allait dans bin \ Debug \ pour la configuration de débogage et bin \ Release \ pour les configurations de version. Dès que j'ai changé la configuration de construction en "bin \" pour toutes les configurations (comme sur l'image ci-dessous), tout a commencé à fonctionner comme il se doit !!!

Configuration de la construction

Je n'ai aucune idée de la raison pour laquelle la séparation de vos versions dans les dossiers Release et Debug devrait entraîner une rupture de la syntaxe de Razor, mais cela semble être dû au fait que quelque chose n'a pas pu trouver les assemblys. Pour moi, les projets qui avaient des problèmes de syntaxe de rasoir sont en fait mes projets de «bibliothèque de rasoirs». Ils sont définis comme des projets d'application, mais je les utilise comme bibliothèques de classes avec RazorGenerator pour compiler mes vues. Lorsque j'ai essayé d'exécuter directement l'un de ces projets, cela a provoqué l'erreur de configuration suivante:

Impossible de charger le fichier ou l'assembly 'System.Web.Helpers, Version = 3.0.0.0, Culture = neutral, PublicKeyToken = 31bf3856ad364e35' ou l'une de ses dépendances. Le système ne peut pas trouver le fichier spécifié.

Cela m'a conduit à essayer de modifier la sortie de construction, car je remarque que pour tous les projets Web, la sortie de construction semble toujours être directement dans le dossier bin, contrairement à la valeur par défaut pour les bibliothèques de classes, qui ont à la fois des dossiers de publication et de débogage.

Sylvia
la source
1
Avoir confirmé par la façon dont vous n'avez pas besoin d'avoir la section system.web \ compilation \ assemblies une fois que les dll sont directement dans le dossier bin. Cela peut revenir à être simplement <compilation debug = "true" targetFramework = "4.5.1" />
Sylvia
2
Sainte vache! Après beaucoup de temps à chercher une solution, cela a finalement résolu mes vues Razor dans un projet de bibliothèque de classes !! Merci beaucoup.
Hullah le
2
Incroyable! Je construisais ma bibliothèque de vues de classe dans le répertoire d'un autre projet et j'ai eu ce problème. Le chemin de construction doit être bin \ pour que cela fonctionne. Maintenant, en utilisant xcopy post build à la place.
GlacialSpoon
1
J'utilise le moteur Razor dans un projet de bibliothèque de classes et j'ai rencontré le même problème. La définition du chemin de sortie sur "bin \" a également résolu ce problème pour moi. Comme GlacialSpoon, je copie l'assemblage lors d'une étape de post-construction dans le dossier de sortie approprié. Ce n'est pas le meilleur moyen, mais au moins, Intellisense, le référencement des assemblys et la coloration syntaxique fonctionne.
Octoate
Il est intéressant de noter que le problème d'origine survient si votre répertoire de sortie personnalisé pointe vers un répertoire parent ala '.. \ some \ dir \'. Mais si vous changez le répertoire de sortie pour dire «some \ dir \» alors tout fonctionne bien. C'est un problème diabolique dans la matrice à coup sûr.
XDS
7

Vous semblez rechercher cette réponse: https://stackoverflow.com/a/4136773/176877

Autrement dit, ouvrez les vues internes \ Web.Config (PAS la racine) et ajoutez l'espace de noms sous la balise 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>

Enregistrez-le, puis fermez et rouvrez le fichier Razor.

Si vous utilisez des zones, vous devrez le faire pour chaque Web.Config de chaque zone.

Visual Studio est devenu plus buggué au fil des ans, il peut donc nécessiter la fermeture du fichier Razor en exécutant une version de débogage, puis la réouverture du fichier Razor, ou dans le pire des cas, le redémarrage de Visual Studio. Mais en fin de compte, il vous présentera le fichier Razor comme si tout dans cette liste d'espaces de noms se trouvait dans des instructions @using en haut de toutes vos vues.

Chris Moschini
la source
4

Dans ASP.NET Core MVC, la solution consiste à ajouter unusing dans _ViewImports.cshtml, au lieu de le placer web.config dans le dossier View lorsque vous travaillez avec 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

Vue

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

Pour moi, je faisais référence à un projet qui était une application console. Il a été configuré pour être construit en tant qu'exe (application console) au lieu de bibliothèque de classes (DLL). Lorsque j'ai changé cela, j'ai pu voir les modèles de ce projet séparé sans problème.

user1619480
la source
Merci @ user1619480, j'ai eu le même problème et dans mon cas, à partir d'une bibliothèque de classes .Net Framework, j'ai ajouté à l'aide de VS 2017 et pour une raison quelconque, le type de sortie était Application console.
danfer
1

J'obtenais la même erreur en essayant d'utiliser des objets Smo dans une vue Razor. Apparemment, c'est parce que Razor ne trouve pas les DLL référencées dans le projet. J'ai résolu ce problème en définissant "Copy Local" sur true pour toutes les dll Smo, mais il pourrait y avoir une meilleure solution (voir le lien de Czechdude ci-dessus) Les modifications @using et web.config sont inutiles car elles ne sont nécessaires que si vous souhaitez omettre l'espace de noms partie des noms de type (par exemple Server au lieu de Microsoft.SqlServer.Management.Smo.Server)

Zar Shardan
la source
1

J'obtenais une erreur similaire après avoir déplacé ma machine de développement de Win7 32bit vers Win7 64bit. Message d'erreur:

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

Il s'avère que j'avais les deux versions dans le GAC. La vue web.configfaisait référence à la v1, mais l'application faisait référence à la v2. Suppression des assemblys référencés et ré-ajout de la v1. de System.Web.WebPages.Razor, etc.

Tim
la source
+1 thx c'était mon dernier point, maintenant je peux déboguer asp.net mvc 4 hohoho!
citykid
1

eh bien, pour moi, c'était différent. Il me manquait l'assemblage de mon projet d'application console avec le projet MVC. Donc, ajouter une référence n'était pas suffisant.

bien cela pourrait aider quelqu'un d'autre. allez dans le fichier racine web.config system.web-> compilation-> ajoutez la référence de votre projet comme ceci.

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

Jawand Singh
la source
1

J'ai également eu le même problème, mais le problème était avec le cadre cible de l'assemblage .

L'assembly référencé était dans .NET Framework 4.6 où le projet a été défini sur .NET Framework 4.5.

J'espère que cela aidera quelqu'un qui a gâché les cadres.

Geeganage
la source
1

Le nom de votre dossier de projet doit être le même. Si le nom de votre projet ou de votre solution est différent, MVC vous fera du mal.

Exemple: si vous créez une nouvelle application et qu'elle obtient le nom par défaut Webapplicaiton1, cet espace de noms sera créé. Alors, disons que vous ne voulez pas avoir cet espace de noms, donc à partir du VS, vous changez partout où vous pouvez voir "MyNamespace". Vous recherchez et remplacez également tout le code de "Webapplication1" et le remplacez par "MyNamespace". Cela modifie également le fichier web.config, de sorte qu'il inculdes

Maintenant, tout fonctionnera, sauf les vues Razor.

RazorViews ne peut pas le trouver, car il existe une sorte de dépendance étrange sur le FOLDERNAME du projet. C'est un design terrible.

J'ai testé cela de manière semi-approfondie en copiant mes fichiers dans une nouvelle solution, et la seule différence est le nom du dossier.

Jens Tand
la source
Incroyable comme c'est ridicule! J'ai renommé le nom du dossier du projet, celui de droite, et j'ai ouvert la solution dans un fichier texte et corrigé la description du dossier! Ça a marché! J'utilise Visual Studio 2019
Daniel
0

Essayez d'ajouter l'espace de noms MyClassesdans lequel vous vous trouvez au web.config sous

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

amurra
la source
0

inclure tout l'espace de noms

@model namespace.myclasses.mymodel
Brettski
la source
0

Aucun de ces https://stackoverflow.com/a/7597360/808128 ne fonctionne pour moi. Même "l'ajout de l'assembly referecene à la section system.web / compilation / assemblies du fichier racine web.config". Il me reste donc les deux méthodes suivantes: 1) ajouter une classe d'encapsulation publique pour mon assembly à laquelle le code Razor peut accéder à cet assembly via ce wrapping; 2) ajoutez simplement la logique d'assembly à une classe publique dans le même assembly où se trouve le code du Razor.

user808128
la source
0

En plus d'apporter des modifications à web.config pour <assemblies>et<namespaces> , j'ai trouvé que GAC'assembler faisait une grande différence. Vous pouvez appliquer la culture et le jeton de clé publique comme n'importe quel assembly .NET principal inscrit globalement.

Certains peuvent frémir à la mention du GAC. Mais en tant que développeur BizTalk, j'ai grandi pour l'adopter.

Des marques
la source
0

Cette solution a fonctionné pour moi (c'est drôle, mais ça marche)

J'ai édité les pages de vue et copié le contenu et collé dedans, je n'ai changé aucun contenu des vues, mais juste édité pour que le studio visuel puisse faire son truc pour suivre les pages, et ensuite tout a commencé à fonctionner

Solution - Il suffit de modifier les pages et de les remplacer par les mêmes pages (a fonctionné pour moi)

Arun Prasad ES
la source
0

dans les modèles spacename, yourClassModel, ajoutez public avant name class

public class yourClassModel{
    prop
}
Milad Jafari
la source
0

Dans mon cas, le package que j'ai essayé d'utiliser faisait référence à la norme .net 2.1 alors que mon projet de bibliothèque de classes razor était défini sur 2.0

Denis Reichelt
la source