113

I'm attempting to create a strongly-typed view based on a class from another assembly. For whatever reason though, my Razor view doesn't seem to have any visibility of other assemblies referenced on my project. e.g.

@model MyClasses.MyModel

results in the error in Visual Studio 2010, "The type or namespace name MyClasses could not be found (are you missing a using directive or an assembly reference?)."

The same class referenced in the standard view engine works fine. I have the same trouble trying to reference the class in the body of my view.

Am I missing something about Razor or do I need to reference the assembly some other way?

radu florescu
  • 4,315
  • 10
  • 60
  • 92
nickwesselman
  • 6,845
  • 2
  • 27
  • 46

20 Answers20

114

There is a new configuration section that is used to reference namespaces for Razor views.

Open the web.config file in your Views folder, and make sure it has the following:

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

Alternatively, you can add using statements to your shared layout:

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

After editing the Web.config, restart Visual Studio to apply the changes.

user247702
  • 23,641
  • 15
  • 110
  • 157
quentin-starin
  • 26,121
  • 7
  • 68
  • 86
  • 19
    This works, however make sure your assemblies are referenced with `Copy Local = true`. External assemblies may not work otherwise. – Terry May 16 '12 at 18:36
  • 2
    It should be noted here that if you are using views from a "virtual" source (such as the DB) instead of using real view files that you must put this in the ROOT web.config file for the code in the views to work. – NightOwl888 Jan 11 '13 at 13:49
  • 2
    @Terry, it appears that Copy local = true is necessary even for some System root namespaced assemblies. – Dan Esparza Jan 24 '13 at 23:19
  • 2
    My assemblies are loaded at runtime, so I can't use web.config file to add them. Is there anything else I can try? Is there a way to import my external views with their own web.config files? It's rather odd because I'm referencing namespaces within the same assembly as my views. – Maksim Vi. Jul 23 '13 at 17:48
  • Restarting Visual Studio is not needed. Simply closing and reopening the Views is enough. – user247702 Sep 09 '15 at 14:06
60

I had the same problem: MVC3 Project MyCore.Web was referencing to MyCore.DBLayer namespace from another project in the same solution (with assembly name MyCoreDBLayer). All objects from MyCore.DBLayer worked perfectly in Controllers and Models but failed in Razor views with an error 'The type or namespace name 'DBLayer' does not exist in the namespace 'MyCore' (are you missing an assembly reference?)' which was obviously not the case.

  • Copy Local option was set to true.
  • Adding "using..." statements in Razor views was useless
  • Adding namespaces to system.web.webPages.razor section was useless as well

Adding assembly referecene to system.web/compilation/assemblies section of the root web.config file fixed the issue. The section now looks like:

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

Omitting version, culture, token was OK for now, but should be fixed in the future.

V.B.
  • 6,236
  • 1
  • 33
  • 56
  • This solution works but it is a bad idea. When I made all my classes internal and made the Web assembly a friend to MyCoreDBLayer, it stopped working. I ended up writing a public classes as an MVC model that wrap around my classes from friend assemblies. I believe one should not use classes other that from MVC's models namespace in Razor views - it is always possible to write a wrapper – V.B. Oct 25 '11 at 08:01
  • This worked for me, I tried adding it to the `Views/web.config` and it worked when it was placed there too. – FarFigNewton Jun 02 '16 at 19:06
18

In my case, the separate project that contained the namespace was a Console Application. Changing it to a Class Library fixed the problem.

Sam
  • 40,644
  • 36
  • 176
  • 219
  • 1
    This solved it for me. First I tried making Class Library (Package), but ran into problems referencing a nuget package I needed. Best not get fancy and just make a basic Class Library (DLL) – redwards510 Nov 17 '15 at 23:02
16

None of the above worked for me either;

  • Dlls were set to Copy Local
  • Adding namespaces to both web.configs did nothing
  • Adding assembly references to system.web\compilation\assemblies also did not help (although I have not removed these references, so it may be that they are needed too)

But I finally found something that worked for me:

It was because I had my Build Output going to bin\Debug\ for Debug configuration and bin\Release\ for Release configuations. As soon as I changed the Build Configuation to "bin\" for All configuations (as per image below) then everything started working as it should!!!

Build Configuration

I have no idea why separating out your builds into Release and Debug folders should cause Razor syntax to break, but it seems to be because something couldn't find the assemblies. For me the projects that were having the razor syntax issues are actually my 'razor library' projects. They are set as Application Projects however I use them as class libraries with RazorGenerator to compile my views. When I actually tried to run one of these projects directly it caused the following Configuration error:

Could not load file or assembly 'System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.

This lead me to trying to change the Build Output, as I notice that for all web projects the Build Output seems to always be directly to the bin folder, unlike the default for class libraries, which have both release and debug folders.

Sylvia
  • 1,022
  • 9
  • 20
  • 1
    Have confirmed by the way that you don't need to have the system.web\compilation\assemblies section once the dlls are directly in the bin folder. This can go back to just being – Sylvia Oct 29 '13 at 10:57
  • 2
    Holy cow! After much time searching for a solution, this finally solved my Razor views in a class library project!! Thank you so much. – Hullah Sep 03 '15 at 21:10
  • 2
    Unbelievable! I was building my class library of views into the directory of another project and had this issue. Build path needs to be bin\ for this to work. Now using post build xcopy instead. – GlacialSpoon Mar 03 '17 at 15:13
  • 1
    I am using the Razor Engine in a class library project and faced the same issue. Setting the output path to "bin\" solved this issue for me, too. Like GlacialSpoon I copy the assembly in a post-build step to the correct output folder. Not the best way, but at least, Intellisense, referencing assemblies and syntax highlighting works. – Octoate Oct 16 '17 at 08:36
  • It's worth noting that the original problem crops up if your custom output directory points to a **parent** directory ala '..\some\dir\'. But if you change the output directory to say 'some\dir\' then everything works fine. This is a diabolical glitch in the matrix for sure. – XDS Jun 28 '20 at 13:57
  • It's 8 years later and I'm still running into this problem: [see my issue](https://stackoverflow.com/q/67405205). In our big monolith application we have many-many projects, of which tens of razor class libraries, which we want to compile together in the `..\bin\ ` directory. This saves **A LOT** of HDD space... So I'm still looking for a solution. _By the way, I think the last part you describe can be solved by setting WebProjectOutputDir, e.g. `.\bin\Debug\` or such. But that doesn't solve the Intellisense issue. – JHBonarius May 14 '21 at 08:25
8

You seem to be looking for this answer: https://stackoverflow.com/a/4136773/176877

That is, open the inner Views\Web.Config (NOT the root one), and add the namespace under the Pages tag:

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

Save that, then close and reopen the Razor file.

If you're using Areas you'll need to do this for each Web.Config in each Area.

Visual Studio has gotten buggier over the years so it may require closing the Razor file running a Debug build then reopening the Razor file, or may in the worst require restarting Visual Studio. But ultimately it will present the Razor file to you as though everything in that namespaces list was in @using statements at the top of all your Views.

Community
  • 1
  • 1
Chris Moschini
  • 36,764
  • 19
  • 160
  • 190
5

In ASP.NET Core MVC the solution is to add a using in _ViewImports.cshtml, instead of putting it web.config in the View folder when working with 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

View

@model LoginViewModel // Add to _ViewImports to make this line work
<div>This is the View for the login screen.</div>
radbyx
  • 9,352
  • 21
  • 84
  • 127
5

For me I was referencing a project that was a console application. It was set to build as an exe (console application) instead of class library (DLL). When I changed this I was able to see the models from that separate project no problem.

user1619480
  • 533
  • 8
  • 18
  • Thanks @user1619480, I had same problem and in my case from a .Net Framework Class Library I added using VS 2017 and for some reason Output type was Console Application. – danfer Feb 13 '19 at 19:37
3

I also had the same issue, but the problem was with the Target framework of the assembly.

The referenced assembly was in .NET Framework 4.6 where the project has set to .NET framework 4.5.

Hope this will help to someone who messed up with frameworks.

Geeganage
  • 182
  • 1
  • 11
2

I was getting a similar error after moving my dev machine from Win7 32bit to Win7 64bit. Error message:

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

Turns out I had both versions in the GAC. The View web.config referenced v1 but the app was referencing v2. Removed the referenced assemblies and re-added v1. of System.Web.WebPages.Razor, etc.

GDP
  • 8,109
  • 6
  • 45
  • 82
Tim
  • 21
  • 1
2

well, for me it was different. I was missing assembly of my console application project with MVC project. So, adding reference was not enough.

well this might help someone else. go to root web.config file system.web -> compilation -> add your project reference like this.

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

Jawand Singh
  • 1,929
  • 1
  • 24
  • 21
2

Your Project FOLDER name needs to be the same. If your Project or Solution name is different, then MVC will hurt you.

Example : If you create a new Application and it gets the default name Webapplicaiton1, then this namespace will be created. So, let us say that you dont want to have this namespace, so from the VS you change everywhere you can see to "MyNamespace". You also search and replace all code from "Webapplication1" and replace it with "MyNamespace". This also changes web.config file, so that it inculdes

Now everything will work, except Razor views.

RazorViews cannot find it, because there is some kind of strange dependency on the FOLDERNAME of the project. It is terrible design.

I have tested this semi-thoroughly by copying my files into a new solution, and the only difference being the foldername.

  • Incredible how ridiculus this is! I have renamed the project folder name, to the right one, and Opened the solution in a text file and corrected the folder description! It worked! I´m using visual studio 2019 – Daniel Aug 09 '19 at 04:28
2

I was getting the same error while trying to use Smo objects in a Razor view. Apparently this is because Razor can't find the DLLs referenced in the project. I resolved this by setting "Copy Local" to true for all Smo dlls, however there might be a better solution (see Czechdude's link above) @using and web.config edits are useless because they are only needed if you wish to omit the namespace part from the type names (for instance Server instead of Microsoft.SqlServer.Management.Smo.Server)

Zar Shardan
  • 5,675
  • 2
  • 39
  • 37
0

In addition to making the web.config changes for <assemblies> and <namespaces>, I found that GAC'ing the assembly made a big difference. You can apply culture and public key token like any core .NET assembly that is registered globally.

Some may shudder at the mention of the GAC. But as a BizTalk developer I've grown to embrace it.

Mark S
  • 401
  • 4
  • 8
0

in spacename models, yourClassModel, add public before name class

public class yourClassModel{
    prop
}
seebiscuit
  • 4,905
  • 5
  • 31
  • 47
Milad Jafari
  • 970
  • 10
  • 15
0

This solution worked for me (It's funny, but works)

I edited the view pages and copied the contents and pasted in it,i didn't change any content of the views, but just edited so the visual studio could do it's thing to track the pages, and afterwards every thing started working

Solution - Just edit the pages and replace with the same pages (Worked for me)

Arun Prasad E S
  • 9,489
  • 8
  • 74
  • 87
0

Try adding the namespace your MyClasses is in to the web.config under

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

amurra
  • 15,221
  • 4
  • 70
  • 87
0

include the entire namespace

@model namespace.myclasses.mymodel
Brettski
  • 19,351
  • 15
  • 74
  • 97
0

In my case the package I tried to use was referencing .net standard 2.1 while my razor class library project was set to 2.0

0

In my case, I was using Razor Views outside of a web application.
Copying the dlls to my bin folder in solution solved the problem.

Bamdad
  • 726
  • 1
  • 11
  • 28
0

None of these https://stackoverflow.com/a/7597360/808128 do work for me. Even "adding assembly referecene to system.web/compilation/assemblies section of the root web.config file". So the two ways remains for me: 1) to add a public wrap class for my assembly that Razor code can access to this assembly through this wrap; 2) just add assembly logic to a public class in the same assembly where the Razor's code is located.

Community
  • 1
  • 1
user808128
  • 511
  • 1
  • 7
  • 24