La visualizzazione basata su Razor non vede gli assembly di riferimento


101

Sto tentando di creare una vista fortemente tipizzata basata su una classe da un altro assembly. Per qualsiasi motivo, tuttavia, la mia vista Razor non sembra avere alcuna visibilità di altri assembly a cui si fa riferimento nel mio progetto. per esempio

@model MyClasses.MyModel

genera l'errore in Visual Studio 2010, " MyClassesImpossibile trovare il nome del tipo o dello spazio dei nomi (manca una direttiva using o un riferimento all'assembly?)."

La stessa classe a cui si fa riferimento nel motore di visualizzazione standard funziona bene. Ho gli stessi problemi cercando di fare riferimento alla classe nel corpo della mia vista.

Mi manca qualcosa su Razor o devo fare riferimento all'assembly in qualche altro modo?


Stai usando l'intero spazio dei nomi? @model namespace.myclasses.mymodel, forse?
Brettski

Risposte:


107

È disponibile una nuova sezione di configurazione usata per fare riferimento agli spazi dei nomi per le visualizzazioni Razor.

Apri il web.configfile nella Viewscartella e assicurati che contenga quanto segue:

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

In alternativa, puoi aggiungere istruzioni using al layout condiviso:

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

Dopo aver modificato il Web.config, riavviare Visual Studio per applicare le modifiche.


18
Funziona, tuttavia assicurati che i tuoi assembly siano referenziati con Copy Local = true. Gli assembly esterni potrebbero non funzionare diversamente.
Terry

1
Va notato qui che se stai usando viste da una sorgente "virtuale" (come il DB) invece di usare file di vista reale, devi metterlo nel file web.config ROOT affinché il codice nelle viste funzioni.
NightOwl888

2
@Terry, sembra che Copy local = true sia necessario anche per alcuni assembly con spazio dei nomi della radice del sistema.
Dan Esparza

2
I miei assembly vengono caricati in fase di esecuzione, quindi non posso utilizzare il file web.config per aggiungerli. C'è qualcos'altro che posso provare? C'è un modo per importare le mie viste esterne con i propri file web.config? È piuttosto strano perché sto facendo riferimento a spazi dei nomi all'interno dello stesso assembly delle mie viste.
Maksim Vi.

Il riavvio di Visual Studio non è necessario. Basta chiudere e riaprire le viste.
user247702

58

Ho avuto lo stesso problema: MVC3 Project MyCore.Web faceva riferimento allo spazio dei nomi MyCore.DBLayer da un altro progetto nella stessa soluzione (con nome assembly MyCoreDBLayer). Tutti gli oggetti da MyCore.DBLayer funzionato perfettamente nel controller e modelli, ma non sono riusciti a vista rasoio con un errore 'Il tipo o dello spazio dei nomi il nome 'livello di database' non esiste nello spazio dei nomi 'MYCORE'(che le manca un riferimento all'assembly?)' , Che è stato ovviamente non è il caso.

  • L'opzione Copia locale era impostata su true.
  • L'aggiunta di istruzioni "using ..." nelle viste Razor era inutile
  • Anche l'aggiunta di spazi dei nomi alla sezione system.web.webPages.razor è stata inutile

L'aggiunta di riferimenti agli assembly alla sezione system.web / compilation / assemblies del file web.config radice ha risolto il problema. La sezione ora ha il seguente aspetto:

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

Omettere versione, cultura e token per ora era OK, ma dovrebbe essere corretto in futuro.


Questa soluzione funziona ma è una cattiva idea. Quando ho reso interne tutte le mie classi e ho reso il Web assembly un amico di MyCoreDBLayer, ha smesso di funzionare. Ho finito per scrivere un corso pubblico come modello MVC che avvolge le mie classi da assemblee di amici. Credo che non si debbano usare classi diverse da quelle dello spazio dei nomi dei modelli MVC nelle viste Razor - è sempre possibile scrivere un wrapper
VB

Questo ha funzionato per me, ho provato ad aggiungerlo a Views/web.confige ha funzionato anche quando è stato posizionato lì.
guanome

18

Nel mio caso, il progetto separato che conteneva lo spazio dei nomi era un'applicazione console. La modifica in una libreria di classi ha risolto il problema.


1
Questo l'ha risolto per me. Per prima cosa ho provato a creare Class Library (Package), ma ho riscontrato problemi con il riferimento a un pacchetto nuget di cui avevo bisogno. Meglio non essere fantasiosi e creare semplicemente una libreria di classi (DLL) di base
redwards510

15

Nessuno dei precedenti ha funzionato neanche per me;

  • Le DLL erano impostate su Copia locale
  • L'aggiunta di spazi dei nomi a entrambi i web.configs non ha fatto nulla
  • Anche l'aggiunta di riferimenti ad assembly a system.web \ compilation \ assembly non ha aiutato (anche se non ho rimosso questi riferimenti, quindi potrebbe essere necessario anche loro)

Ma finalmente ho trovato qualcosa che ha funzionato per me:

Era perché avevo il mio output di compilazione che andava in bin \ Debug \ per la configurazione di debug e bin \ Release \ per le configurazioni di rilascio. Non appena ho modificato la configurazione della build in "bin \" per tutte le configurazioni (come da immagine sotto), tutto ha iniziato a funzionare come dovrebbe !!!

Configurazione build

Non ho idea del motivo per cui separare le build nelle cartelle Release e Debug dovrebbe causare l'interruzione della sintassi di Razor, ma sembra che qualcosa non sia riuscito a trovare gli assembly. Per me i progetti con problemi di sintassi razor sono in realtà i miei progetti di "libreria razor". Sono impostati come progetti applicativi, tuttavia li uso come librerie di classi con RazorGenerator per compilare le mie viste. Quando ho effettivamente provato a eseguire uno di questi progetti direttamente, ha causato il seguente errore di configurazione:

Impossibile caricare il file o l'assembly "System.Web.Helpers, Version = 3.0.0.0, Culture = neutral, PublicKeyToken = 31bf3856ad364e35" o una delle sue dipendenze. Il sistema non trova il file specificato.

Questo mi ha portato a provare a cambiare l'output di build, poiché ho notato che per tutti i progetti web l'output di build sembra essere sempre direttamente nella cartella bin, a differenza di quello predefinito per le librerie di classi, che hanno sia cartelle di rilascio che di debug.


1
Ho confermato dal modo in cui non è necessario avere la sezione system.web \ compilation \ assembly una volta che le dll sono direttamente nella cartella bin. Questo può tornare a essere <compilation debug = "true" targetFramework = "4.5.1" />
Sylvia,

2
Mucca sacra! Dopo molto tempo alla ricerca di una soluzione, questo ha finalmente risolto le mie visualizzazioni Razor in un progetto di libreria di classi !! Grazie mille.
Hullah

2
Incredibile! Stavo costruendo la mia libreria di classi di viste nella directory di un altro progetto e ho avuto questo problema. Il percorso di compilazione deve essere bin \ affinché funzioni. Ora usa invece post build xcopy.
GlacialSpoon

1
Sto usando il motore Razor in un progetto di libreria di classi e ho riscontrato lo stesso problema. Anche l'impostazione del percorso di output su "bin \" ha risolto questo problema. Come GlacialSpoon, copio l'assembly in una fase di post-build nella cartella di output corretta. Non il modo migliore, ma almeno Intellisense, che fa riferimento agli assembly e all'evidenziazione della sintassi funziona.
Octoate

Vale la pena notare che il problema originale si presenta se la directory di output personalizzata punta a una directory padre come ".. \ some \ dir \". Ma se cambi la directory di output per dire "some \ dir \", allora tutto funziona correttamente. Questo è sicuramente un problema tecnico diabolico nella matrice.
XDS

7

Sembra che tu stia cercando questa risposta: https://stackoverflow.com/a/4136773/176877

Cioè, apri il Views \ Web.Config interno (NON quello root) e aggiungi lo spazio dei nomi sotto il tag 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>

Salvalo, quindi chiudi e riapri il file Razor.

Se stai usando Aree, dovrai farlo per ogni Web.Config in ogni Area.

Visual Studio è diventato più aggiornato nel corso degli anni, quindi potrebbe essere necessario chiudere il file Razor che esegue una build di debug e quindi riaprire il file Razor o, nel peggiore dei casi, potrebbe richiedere il riavvio di Visual Studio. Ma alla fine ti presenterà il file Razor come se tutto in quell'elenco di spazi dei nomi fosse nelle istruzioni @using nella parte superiore di tutte le tue visualizzazioni.


4

In ASP.NET Core MVC la soluzione è aggiungere un usingin _ViewImports.cshtml, invece di metterlo web.config nella cartella Visualizza quando si lavora 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

Visualizza

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

3

Per me stavo facendo riferimento a un progetto che era un'applicazione console. È stato impostato per essere compilato come exe (applicazione console) anziché come libreria di classi (DLL). Quando ho cambiato questo, sono stato in grado di vedere i modelli di quel progetto separato senza problemi.


Grazie @ user1619480, ho avuto lo stesso problema e nel mio caso da una libreria di classi .Net Framework ho aggiunto utilizzando VS 2017 e per qualche motivo il tipo di output era Applicazione console.
danfer

1

Ho ricevuto lo stesso errore durante il tentativo di utilizzare oggetti Smo in una vista Razor. Apparentemente questo è perché Razor non riesce a trovare le DLL a cui si fa riferimento nel progetto. Ho risolto il problema impostando "Copia locale" su true per tutte le dll di Smo, tuttavia potrebbe esserci una soluzione migliore (vedi il collegamento di Czechdude sopra) @using e le modifiche web.config sono inutili perché sono necessarie solo se desideri omettere lo spazio dei nomi parte dai nomi dei tipi (ad esempio Server invece di Microsoft.SqlServer.Management.Smo.Server)


1

Ho ricevuto un errore simile dopo aver spostato la mia macchina di sviluppo da Win7 a 32 bit a Win7 a 64 bit. Messaggio di errore:

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

È venuto fuori che avevo entrambe le versioni nel GAC. La vista web.configfaceva riferimento a v1 ma l'app faceva riferimento a v2. Rimossi gli assembly a cui si fa riferimento e aggiunto nuovamente v1. di System.Web.WebPages.Razor, ecc.


+1 grazie questo era il mio punto finale, ora posso eseguire il debug di asp.net mvc 4 hohoho!
citykid

1

beh, per me era diverso. Mi mancava l'assemblaggio del mio progetto di applicazione console con il progetto MVC. Quindi, l'aggiunta di riferimenti non era sufficiente.

beh questo potrebbe aiutare qualcun altro. vai al file web.config di root system.web-> compilation-> aggiungi il riferimento al tuo progetto in questo modo.

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


1

Ho anche avuto lo stesso problema, ma il problema era con il framework Target dell'assembly .

L'assembly a cui si fa riferimento era in .NET Framework 4.6, dove il progetto è stato impostato su .NET framework 4.5.

Spero che questo aiuti a qualcuno che ha incasinato i framework.


1

Il nome della cartella del progetto deve essere lo stesso. Se il nome del progetto o della soluzione è diverso, MVC ti danneggerà.

Esempio: se crei una nuova applicazione e ottiene il nome predefinito Webapplicaiton1, verrà creato questo spazio dei nomi. Quindi, diciamo che non vuoi avere questo spazio dei nomi, quindi da VS cambi ovunque puoi vedere in "MyNamespace". Puoi anche cercare e sostituire tutto il codice da "Webapplication1" e sostituirlo con "MyNamespace". Questo cambia anche il file web.config, in modo che includa

Ora tutto funzionerà, tranne le visualizzazioni Razor.

RazorViews non riesce a trovarlo, perché esiste una sorta di strana dipendenza dal FOLDERNAME del progetto. È un design terribile.

L'ho testato a fondo copiando i miei file in una nuova soluzione e l'unica differenza è il nome della cartella.


Incredibile quanto sia ridicolo questo! Ho rinominato il nome della cartella del progetto, a destra, e ho aperto la soluzione in un file di testo e ho corretto la descrizione della cartella! Ha funzionato! Sto usando Visual Studio 2019
Daniel

0

Prova ad aggiungere lo spazio dei nomi in cui ti MyClassestrovi a web.config sotto

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


0

includere l'intero spazio dei nomi

@model namespace.myclasses.mymodel

0

Nessuno di questi https://stackoverflow.com/a/7597360/808128 funziona per me. Anche "l'aggiunta di riferimenti ad assembly alla sezione system.web / compilation / assembly del file web.config di root". Quindi i due modi rimangono per me: 1) aggiungere una classe di wrapping pubblica per il mio assembly a cui il codice Razor può accedere a questo assembly attraverso questo wrap; 2) aggiungi semplicemente la logica dell'assembly a una classe pubblica nello stesso assembly in cui si trova il codice di Razor.


0

Oltre ad apportare modifiche al web.config per <assemblies>e <namespaces>, ho scoperto che GAC'ing l'assembly ha fatto una grande differenza. È possibile applicare la cultura e il token della chiave pubblica come qualsiasi assembly .NET di base registrato a livello globale.

Alcuni potrebbero rabbrividire alla menzione del GAC. Ma come sviluppatore BizTalk sono cresciuto per abbracciarlo.


0

Questa soluzione ha funzionato per me (è divertente, ma funziona)

Ho modificato le pagine di visualizzazione e copiato i contenuti e incollato al suo interno, non ho modificato alcun contenuto delle visualizzazioni, ma ho solo modificato in modo che lo studio visivo potesse fare di tutto per tenere traccia delle pagine, dopodiché ogni cosa ha iniziato a funzionare

Soluzione: modifica le pagine e sostituiscile con le stesse (ha funzionato per me)


0

in spacename models, yourClassModel, aggiungi public prima del name class

public class yourClassModel{
    prop
}

0

Nel mio caso il pacchetto che ho provato a utilizzare faceva riferimento allo standard .net 2.1 mentre il mio progetto di libreria di classi razor era impostato su 2.0

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.