A visão baseada no Razor não vê montagens referenciadas

101

Estou tentando criar um modo de exibição fortemente tipado com base em uma classe de outro assembly. Por alguma razão, porém, minha visualização Razor não parece ter qualquer visibilidade de outras montagens referenciadas em meu projeto. por exemplo

@model MyClasses.MyModel

resulta no erro no Visual Studio 2010, "O tipo ou nome do namespace MyClassesnão foi encontrado (está faltando uma diretiva using ou uma referência do assembly?)."

A mesma classe referenciada no mecanismo de exibição padrão funciona bem. Tenho o mesmo problema ao tentar fazer referência à classe no corpo do meu ponto de vista.

Estou perdendo algo sobre o Razor ou preciso fazer referência à montagem de outra forma?

nickwesselman
fonte
Você está usando todo o namespace? @model namespace.myclasses.mymodel, talvez?
Brettski de

Respostas:

107

Há uma nova seção de configuração que é usada para referenciar namespaces para visualizações do Razor.

Abra o web.configarquivo em sua Viewspasta e verifique se ele contém o seguinte:

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

Como alternativa, você pode adicionar instruções usando ao seu layout compartilhado:

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

Depois de editar o Web.config, reinicie o Visual Studio para aplicar as alterações.

Quentin-Starin
fonte
18
Isso funciona, no entanto, certifique-se de que seus assemblies sejam referenciados com Copy Local = true. Os conjuntos externos podem não funcionar de outra forma.
Terry
1
Deve-se notar aqui que se você estiver usando visualizações de uma fonte "virtual" (como o banco de dados) em vez de usar arquivos de visualização reais, você deve colocar isso no arquivo web.config ROOT para que o código nas visualizações funcione.
NightOwl888
2
@Terry, parece que Copiar local = true é necessário mesmo para alguns assemblies com namespaces de raiz do Sistema.
Dan Esparza
2
Meus assemblies são carregados em tempo de execução, então não posso usar o arquivo web.config para adicioná-los. Posso tentar mais alguma coisa? Existe uma maneira de importar minhas visualizações externas com seus próprios arquivos web.config? É bastante estranho porque estou fazendo referência a namespaces dentro do mesmo assembly que minhas visualizações.
Maksim Vi.
Reiniciar o Visual Studio não é necessário. Basta fechar e reabrir as visualizações.
user247702
58

Eu tive o mesmo problema: MVC3 Project MyCore.Web estava fazendo referência ao namespace MyCore.DBLayer de outro projeto na mesma solução (com o nome do assembly MyCoreDBLayer). Todos os objetos de MyCore.DBLayer funcionaram perfeitamente em controladores e modelos, mas falharam em visualizações Razor com um erro 'O tipo ou nome do namespace' DBLayer 'não existe no namespace' MyCore '(está faltando uma referência de assembly?)' Que foi obviamente não é o caso.

  • A opção Copiar local foi definida como verdadeira.
  • Adicionar instruções "usando ..." nas visualizações do Razor era inútil
  • Adicionar namespaces à seção system.web.webPages.razor também era inútil

Adicionar referecene de assembly à seção system.web / compilation / assemblies do arquivo web.config raiz corrigiu o problema. A seção agora se parece com:

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

A omissão de versão, cultura e token estava OK por enquanto, mas deve ser corrigido no futuro.

VB
fonte
Esta solução funciona, mas é uma má ideia. Quando tornei todas as minhas classes internas e tornei o Web assembly um amigo de MyCoreDBLayer, ele parou de funcionar. Acabei escrevendo classes públicas como um modelo MVC que envolve minhas classes de assemblies de amigos. Acredito que não se deva usar classes que não sejam do namespace de modelos do MVC nas visualizações do Razor - sempre é possível escrever um wrapper
VB
Isso funcionou para mim, tentei adicioná-lo ao Views/web.confige funcionou quando foi colocado lá também.
guanome
18

No meu caso, o projeto separado que continha o namespace era um aplicativo de console. Mudá-lo para uma Biblioteca de Classes corrigiu o problema.

Sam
fonte
1
Isso resolveu para mim. Primeiro tentei fazer Class Library (Package), mas tive problemas ao fazer referência a um pacote nuget de que precisava. Melhor não fantasiar e apenas fazer uma Biblioteca de Classes (DLL)
básica
15

Nenhuma das opções acima funcionou para mim também;

  • Dlls foram configurados para copiar local
  • Adicionar namespaces a web.configs não adiantou nada
  • Adicionar referências de assembly a system.web \ compilation \ assemblies também não ajudou (embora eu não tenha removido essas referências, então pode ser que elas também sejam necessárias)

Mas finalmente encontrei algo que funcionou para mim:

Foi porque eu tinha meu Build Output indo para bin \ Debug \ para configuração de Debug e bin \ Release \ para configurações de versão. Assim que alterei a configuração de construção para "bin \" para todas as configurações (conforme imagem abaixo), tudo começou a funcionar como deveria !!!

Configuração de compilação

Não tenho ideia de por que separar seus builds nas pastas Release e Debug deveria causar a quebra da sintaxe do Razor, mas parece que algo não conseguiu encontrar os assemblies. Para mim, os projetos que apresentavam problemas de sintaxe do razor são, na verdade, meus projetos de 'biblioteca do razor'. Eles são definidos como Projetos de aplicação, entretanto eu os uso como bibliotecas de classes com RazorGenerator para compilar minhas visualizações. Quando eu realmente tentei executar um desses projetos diretamente, isso causou o seguinte erro de configuração:

Não foi possível carregar o arquivo ou assembly 'System.Web.Helpers, Version = 3.0.0.0, Culture = neutral, PublicKeyToken = 31bf3856ad364e35' ou uma de suas dependências. O sistema não pode encontrar o arquivo especificado.

Isso me levou a tentar alterar o Build Output, pois percebi que, para todos os projetos da web, o Build Output parece estar sempre diretamente para a pasta bin, ao contrário do padrão para bibliotecas de classe, que têm pastas de liberação e depuração.

Sylvia
fonte
1
Confirmei que você não precisa ter a seção system.web \ compilation \ assemblies, uma vez que as dlls estão diretamente na pasta bin. Isso pode voltar a ser apenas <compilation debug = "true" targetFramework = "4.5.1" />
Sylvia
2
Vaca sagrada! Depois de muito tempo procurando por uma solução, isso finalmente resolveu minhas visualizações do Razor em um projeto de biblioteca de classe !! Muito obrigado.
Hullah,
2
Inacreditável! Eu estava criando minha biblioteca de classes de visualizações no diretório de outro projeto e tive esse problema. O caminho de construção precisa ser bin \ para que funcione. Agora, usando o xcopy pós-compilação.
GlacialSpoon
1
Estou usando o Razor Engine em um projeto de biblioteca de classe e enfrentei o mesmo problema. Definir o caminho de saída como "bin \" resolveu esse problema para mim também. Como o GlacialSpoon, copio a montagem em uma etapa de pós-construção para a pasta de saída correta. Não é a melhor maneira, mas pelo menos o Intellisense, referenciando assemblies e realce de sintaxe funciona.
Octoato
É importante notar que o problema original surge se seu diretório de saída customizado apontar para um diretório pai ala '.. \ some \ dir \'. Mas se você alterar o diretório de saída para 'algum \ dir \', então tudo funcionará bem. Esta é uma falha diabólica na matriz, com certeza.
XDS
7

Você parece estar procurando por esta resposta: https://stackoverflow.com/a/4136773/176877

Ou seja, abra o Views \ Web.Config interno (NÃO o raiz) e adicione o namespace na 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>

Salve isso, feche e reabra o arquivo Razor.

Se você estiver usando áreas, você precisará fazer isso para cada Web.Config em cada área.

O Visual Studio ficou mais problemático com o passar dos anos, portanto, pode ser necessário fechar o arquivo Razor executando uma compilação de depuração e, em seguida, reabrir o arquivo Razor ou, na pior das hipóteses, exigir a reinicialização do Visual Studio. Mas, no final das contas, ele apresentará o arquivo Razor a você como se tudo na lista de namespaces estivesse em instruções @using no topo de todas as suas visualizações.

Chris Moschini
fonte
4

No ASP.NET Core MVC, a solução é adicionar um usingem _ViewImports.cshtml, em vez de colocá-lo web.config na pasta View ao trabalhar com a 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

Visão

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

Para mim, estava me referindo a um projeto que era um aplicativo de console. Ele foi configurado para ser construído como um exe (aplicativo de console) em vez de uma biblioteca de classes (DLL). Quando mudei isso, pude ver os modelos daquele projeto separado sem problemas.

user1619480
fonte
Obrigado @ user1619480, tive o mesmo problema e, no meu caso, de uma biblioteca de classes .Net Framework, adicionei usando o VS 2017 e por algum motivo o tipo de saída era Aplicativo de console.
danfer
1

Eu estava recebendo o mesmo erro ao tentar usar objetos Smo em uma visualização do Razor. Aparentemente, isso ocorre porque o Razor não consegue encontrar as DLLs referenciadas no projeto. Resolvi isso definindo "Copiar local" como verdadeiro para todas as dlls Smo, no entanto, pode haver uma solução melhor (consulte o link do Czechdude acima). As edições de @using e web.config são inúteis porque são necessárias apenas se você quiser omitir o namespace parte dos nomes de tipo (por exemplo, Servidor em vez de Microsoft.SqlServer.Management.Smo.Server)

Zar Shardan
fonte
1

Eu estava recebendo um erro semelhante depois de mover minha máquina de desenvolvimento de Win7 de 32 bits para Win7 de 64 bits. Mensagem de erro:

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

Acontece que eu tinha as duas versões no GAC. A visualização web.configreferenciava a v1, mas o aplicativo fazia referência à v2. Removidos os assemblies referenciados e v1 novamente adicionados. de System.Web.WebPages.Razor, etc.

Tim
fonte
+1 thx este foi meu ponto final, agora posso depurar asp.net mvc 4 hohoho!
citykid
1

bem, para mim foi diferente. Eu estava perdendo a montagem do meu projeto de aplicativo de console com o projeto MVC. Portanto, adicionar referência não foi suficiente.

bem, isso pode ajudar outra pessoa. vá para o arquivo web.config root system.web-> compilation-> adicione sua referência de projeto desta forma.

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

Jawand Singh
fonte
1

Eu também tive o mesmo problema, mas o problema era com a estrutura de destino da montagem .

O assembly referenciado estava no .NET Framework 4.6, onde o projeto foi definido como .NET framework 4.5.

Espero que isso ajude alguém que mexeu com frameworks.

Geeganage
fonte
1

O nome da FOLDER do seu projeto deve ser o mesmo. Se o nome do seu projeto ou solução for diferente, MVC irá prejudicá-lo.

Exemplo: se você criar um novo aplicativo e ele obtiver o nome padrão Webapplicaiton1, este namespace será criado. Então, vamos dizer que você não quer ter este namespace, então do VS você muda em todos os lugares que pode ver para "MyNamespace". Você também pesquisa e substitui todo o código de "Webapplication1" e substitui-o por "MyNamespace". Isso também muda o arquivo web.config, de modo que inculde

Agora tudo funcionará, exceto as visualizações do Razor.

RazorViews não consegue encontrá-lo, porque há algum tipo de dependência estranha na FOLDERNAME do projeto. É um design terrível.

Eu testei isso quase completamente, copiando meus arquivos para uma nova solução, e a única diferença é o nome da pasta.

Jens Tand
fonte
Incrível como isso é ridículo! Eu renomei o nome da pasta do projeto, para o correto, e abri a solução em um arquivo de texto e corrigi a descrição da pasta! Funcionou! Estou usando o Visual Studio 2019
Daniel
0

Tente adicionar o namespace MyClassesem que está ao web.config em

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

amurra
fonte
0

inclui todo o namespace

@model namespace.myclasses.mymodel
Brettski
fonte
0

Nenhum desses https://stackoverflow.com/a/7597360/808128 funciona para mim. Até mesmo "adicionando referecene de montagem à seção system.web / compilation / assemblies do arquivo web.config raiz". Portanto, restam duas maneiras para mim: 1) adicionar uma classe de wrap público para meu assembly que o código do Razor pode acessar a esse assembly por meio desse wrap; 2) basta adicionar a lógica do assembly a uma classe pública no mesmo assembly onde o código do Razor está localizado.

user808128
fonte
0

Além de fazer as alterações do web.config para <assemblies>e <namespaces>, descobri que fazer o GAC na montagem fez uma grande diferença. Você pode aplicar cultura e token de chave pública como qualquer assembly .NET principal registrado globalmente.

Alguns podem estremecer com a menção do GAC. Mas, como desenvolvedor de BizTalk, aprendi a adotá-lo.

Mark S
fonte
0

Esta solução funcionou para mim (é engraçado, mas funciona)

Eu editei as páginas de visualização e copiei o conteúdo e colei nelas, não mudei nenhum conteúdo das visualizações, apenas editei para que o estúdio visual pudesse fazer o acompanhamento das páginas e depois tudo começou a funcionar

Solução - Apenas edite as páginas e substitua pelas mesmas páginas (funcionou para mim)

Arun Prasad ES
fonte
0

em modelos de nome de espaço, yourClassModel, adicione público antes da classe de nome

public class yourClassModel{
    prop
}
Milad Jafari
fonte
0

No meu caso, o pacote que tentei usar fazia referência ao .net padrão 2.1, enquanto meu projeto de biblioteca de classes de navalha estava definido como 2.0

Denis Reichelt
fonte