Razor-based view doesn't see referenced assemblies - asp.net-mvc

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?

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.

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.

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

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

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.

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>

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.

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.

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)

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.

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>

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.

Try adding the namespace your MyClasses is in to the web.config under
<pages>
<namespaces></namespaces>
</pages>

include the entire namespace
#model namespace.myclasses.mymodel

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.

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.

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)

in spacename models, yourClassModel, add public before name class
public class yourClassModel{
prop
}

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

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.

Related

MVC 4 #Scripts "does not exist"

I have just created an ASP.NET MVC 4 project and used Visual Studio 2012 RC to create a Controller and Razor Views for Index and Create Actions.
When I came to run the application, and browsed to the Create view, the following error was shown:
Compiler Error Message: CS0103: The name 'Scripts' does not exist in
the current context
The problem is the following code which was added automatically to the bottom of the View:
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Why does Scripts not exist?
I looked at the base Web Page class in Assembly System.Web.Mvc.dll, v4.0.0.0
I can see the following helper properties available:
Ajax
Html
Url
But nothing named Scripts.
Any ideas?
EDIT:
My Web.config file looks like this (untouched from the one that Visual Studio created):
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.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" />
</namespaces>
</pages>
</system.web.webPages.razor>
EDIT #2:
People are blogging about using the #Scripts helper:
SCOTT HANSELMAN Blog
Codebetter.com
Yet having just installed Visual Studio 2012 RC onto a fresh Windows 8 install I am still unable to use #Scripts even though Visual Studio adds it to the generated View!
Solutions are presented below.
I am not sure how to close this, because in the end an update seemed to resolve the issue. I double checked I had performed a clean install, using a new project. But the same failing project I had made works fine now after various updates and no manual obvious intervention. Thanks for all of the thoughts but there was definitely an issue at the time ;)
The key here is to add
<add namespace="System.Web.Optimization" />
to BOTH web.config files. My scenario was that I had System.Web.Optimization reference in both project and the main/root web.config but #Scripts still didn't work properly. You need to add the namespace reference to the Views web.config file to make it work.
UPDATE:
Since the release of MVC 4 System.Web.Optimization is now obsolete. If you're starting with a blank solution you will need to install the following nuget package:
Install-Package Microsoft.AspNet.Web.Optimization
You will still need to reference System.Web.Optimization in your web.config files. For more information see this topic:
How to add reference to System.Web.Optimization for MVC-3-converted-to-4 app
As many pointed out, restart of VS could be required after the above steps to make this work.
#Styles and #Scripts are 2 new helpers provided by System.Web.Optimization library. As the name suggests, they bundle and minify CSS and JavaScript files or resources respectively.
Try including the namespace System.Web.Optimization either by #using directive or through web.config
http://ofps.oreilly.com/titles/9781449320317/ch_ClientOptimization.html#BundlingAndMinification
UPDATE
Microsoft has moved the bundling/minification to a separate package called Microsoft.AspNet.Web.Optimization. You can download the assembly from nuget.
This post will be useful to you.
There was one small step missing from the above, which I found on another post. After adding
<add namespace="System.Web.Optimization" />
to your ~/Views/web.config namespaces, close and re-open Visual Studio. This is what I had to do to get this working.
I am using areas, and have just come up against this issue, I just copied the namespaces from the root web.config to the areas web. config and it now works!!
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Optimization" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages" />
I had the same problem and I used WinMerge to help me track this down. But as I researched it more, I found that Rick has the perfect blog post for it.
Summary:
Add <add namespace="System.Web.Optimization"/> to both web.config files
Run Install-Package -IncludePrerelease Microsoft.AspNet.Web.Optimization
Update Bundling code
Update Layout file
The last step is to update 10 other libraries. I didn't and it worked fine. So looks like you can procrastinate this one (unless I already updated 1 or more of them). :)
I had the same issue:
The System.Web.Optimization version I was using was outdated for MVC4 RC.
I updated my packages using the package manager in VS 2010.
In this MSDN blog, Mr. Andy talks about how to update your MVC 4 Beta project to MVC 4 RC. Updating my packages got the Scripts (particularly the web optimization one) to resolve for me:
To install the latest System.Web.Optimization package, use Package Manager Console (Tools -> Library Package Manager -> Package Manager Console) and run the below command:
Install-Package -IncludePrerelease Microsoft.AspNet.Web.Optimization
Use the System.Web.Optimization file included in the package in your references.
To update other packages:
Tools menu -> Library Package Manager -> Manage NuGet Packages for Solution.
Create a new MVC 4 RC internet application and run it. Navigate to Login which uses the same code
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
What allows Login.cshtml to work is the the Views\Web.config file (not the app root version) contains
<namespaces>
<add namespace="System.Web.Optimization"/>
</namespaces>
Why is your Create view not working and Login is?
Import System.Web.Optimization on top of your razor view as follows:
#using System.Web.Optimization
I ran into this problem, however while running the command:
Install-Package -IncludePrerelease Microsoft.AspNet.Web.Optimization
I received the cryptic message (gotta love a great pun before the first cup of coffee):
Install-Package : The specified cryptographic algorithm is not
supported on this platform.
I am running this on Windows XP SP3 (not by choice) and what I found was that I had to follow the instructions posted by the user artsnob on the ASP.NET Forum
Please uninstall the Nuget and try re-installing it. If you are unable to do this, login as an Administrator.
Go to Tools=> Extension Manager => Select "Nuget Package Manager" => UnInstall
Install it again, by searching "Nuget" => Install.
If it did not work, please try installing, 1.7.x version as I mentioned in the previous post (It doesn't mean, you have to use the previous version, if it works fine, we can report this bug, and get the patches for the latest version).
Once I ran this I could then run the command line to update the Web.Optimization.
Hope this saves someone some digging.
Just write
#section Scripts{
<script src="#System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/bundles/jqueryval")"></script>
}
I upgraded from Beta to RC and faced 'Scripts' does not exist issue. Surfed all over the web and the final solution is what N40JPJ said plus another workaroudn:
Copy the following in View\Web.config :
<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="System.Web.Optimization"/>
<add namespace="System.Web.Helpers"/>
</namespaces>
and the following inside View\Shared_Layout.cshtml
#if (IsSectionDefined("scripts"))
{
#RenderSection("scripts", required: false)
}
Hope it helps.
Apparently you have created an 'Empty' project type without 'Scripts' folder.
My advice
-create a 'Basic' project type with full 'Scripts' folder.
With respect to all developers.
just remove/ hide the code from create & Edit razor view of your controller.
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
: remove view page.
: add namespace webconfig (in view directory)
: create view an try!
good luck...
One more for the pot - spent ages trying to work out the same problem - even though it was defined in the web.config for root and the root of Views. Turns out I'd mistakenly added it to the <system.web><pages><namespaces>, and not <system.web**.webPages.razor**><pages><namespaces> element.
Really easy to miss that!
When I enter on a page that haves this code:
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
This error occurs: Error. An error occurred while processing your request.
And this exception are recorded on my logs:
System.Web.HttpException (0x80004005): The controller for path '/bundles/jqueryval' was not found or does not implement IController.
em System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType)
...
I have tried all tips on this page and none of them solved for me. So I have looked on my Packages folder and noticed that I have two versions for System.Web.Optmization.dll:
Microsoft.AspNet.Web.Optimization.1.1.0 (v1.1.30515.0 - 68,7KB)
Microsoft.Web.Optimization.1.0.0-beta
(v1.0.0.0 - 304KB)
My project was referencing to the older beta version. I only changed the reference to the newer version (69KB) and eveything worked fine.
I think it might help someone.
That has an obvious solution. I had the same problem later. Not related to Assembly References or ... .It'll occur In hierarchy calling of MVC Partial views, when you have complicated page structures. So calling/rendering each part separately on each page (maybe a master page or partial) will cause to not see required parts of page like the bellow code :
#RenderSection("Scripts", required: false)
That simply forces page to find and render related section and in case of failure shows you an error message like you.
So I suggest you to trace your pages (like program trace) from master to all of its partials to Detect Dependencies. Maybe it be a terrible work, but no other choices available here.
Not that according to my experience, some conditional situations in programming causes not to show you the right error causes the problem.
I had this issue after I added an Area to a project that didn't have any.
To get rid of it just copied the web.config withing root Views folder to the Views folder of the area and it started working.
For me this solved the problem, in NuGet package manager console write following:
update-package microsoft.aspnet.mvc -reinstall
When i started using MVC4 recently i faced the above issue while creating a project with the empty templates.
Steps to fix the issue.
Goto TOOLS --> Library Package Manager --> Packager Manager Console
Paste the below command and press enter
Install-Package Microsoft.AspNet.Web.Optimization
Note: wait for successful installation.
Goto Web.Config file in root level and add below namespace in pages namespace section.
add <namespace="System.Web.Optimization" />
Goto Web.Config in Views folder and follow the step 2.
Build the solution and run.
The Package mentioned in step 1 will add few system libraries into the solution references like System.Web.Optimization is not a default reference for empty templates in MVC4.
I hope this helps.
Thank you
I had a very similar error when upgrading a project from MVC3 to MVC4.
Compiler Error Message: CS0103: The name [blah] does not exist in the
current context
In my case, I had outdated version numbers in several of my Web.Configs.
I needed to update the System.Web.Mvc version number from "3.0.0.0" to "4.0.0.0" in every Web.Config in my project.
I needed to update all of my System.Web.WebPages, System.Web.Helpers, and System.Web.Razor version numbers from "1.0.0.0" to "2.0.0.0" in every Web.Config in my project.
Ex:
<configSections>
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
...
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Helpers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.WebPages, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</assemblies>
</compilation>
Be sure to review the Web.Configs in each of your Views directories.
You can read more about Upgrading an ASP.NET MVC 3 Project to ASP.NET MVC 4.
If you added to your web.config and it still shows message, then you need to close your project and reopen it, now it will exist and #Styles.Render("") and #Scripts.Render() will work fine.
I solve this problem in MvcMusicStore by add this part of code in _Layout.cshtml
#if (IsSectionDefined("scripts"))
{
#RenderSection("scripts", required: false)
}
and remove this code from Edit.cshtml
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Try this:
#section Scripts
{
Scripts.Render("~/bundles/jqueryval") // <- without ampersand at the begin
}

mvc3 razor page don't find Namespace

I read a lot of similar questions out there, but I can't solve my particular problem...
In my MVC3 project I use an external library. I can use this library everywhere, but not in my razor views.
So, reading some similar question on SO, I found out that I should register this library into the <system.web><compilation><assemblies> section.
Trying to do this, I ended up with a portion of my web.config like this
<compilation debug="true" targetFramework="4.0">
<assemblies>
... <!-- default assembly registration, like System.Web.something -->
<add assembly="MailBee.Net.dll, Version=7.1.4.348, Culture=neutral, PublicKeyToken=cd85b70fb26f9fc1" />
</assemblies>
</compilation>
But still don't work... or to be more precise, this broke up all the project at runtime. If I launch the project, it crashes telling me Impossibile to load assembly 'MailBee.Net.dll, Version=7.1.4.348, Culture=neutral, PublicKeyToken=cd85b70fb26f9fc1' or one of its dependency
The dll for sure is in the /bin folder of the web application and, deleting the declaration in the web.config file, I cau use it in all the project but in the views page.
Any idea?
There are a few possible problems:
MailBee.Net.dll has a dependancey/requirement on another dll that is not in your solution.
MailBee.Net.dll is not the same x86/x64 version as your project/hosting solution (visual studio/iis express)
Additionally, in your web.config file located in the Views directory you should add something like the following:
<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="<NamespaceYouNeedInYourViews>" />
</namespaces>
</pages>
</system.web.webPages.razor>
I got it!
It's not a problem of dependencies, nor a problem of declaring the assembly or the namespace somewhere... it's just that that library, for some reason, is not copied into the bin folder when building the project!
Or better, the reason is that the property "Copy local" on the referenced library is set to false, but I have no idea why: every other third party library I tried with haven't this behaviour...

Why don't my Html Helpers have intellisense?

I can't get intellisense for my own html helpers. My CustomHtmlHelpers.cs looks like this:
using System.Web.Mvc;
using System.Text;
using System.Web;
namespace laget.Web.Helpers
{
public static class CustomHtmlHelpers
{
//MY HELPERS
}
}
and in my Web.config:
<pages>
<namespaces>
<add namespace="laget.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages"/>
<add namespace="System.Web.Helpers" />
</namespaces>
</pages>
If I put <#using laget.Web.Helpers> in my view, I get the intellisense issue fixed.
Should it not be enough with the code in Web.config?
Sometimes it doesn't seem to work right away. Try closing the .cshtml file, and re-opening it. Then if that doesn't work, try restarting Visual Studio. Also make sure you actually compiled your project, intellisense won't work with non-compiled helpers.
I'm pretty sure that you're not editing the correct Web.config file.
You need to add your namespace to the one in your Views directory.
<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="laget.Web.Helpers" />
</namespaces>
</pages>
</system.web.webPages.razor>
You actually don't need to restart Visual Studio in most cases. All you need to do is close the .cshtml file and reopen it!
It needs it on the local page. I'm pretty sure this has to do with Namespace resolution. It isn't exactly sure what you are referring to without the local using statement.
I ran into this today as well. Sometimes just closing the Razor view's window in Visual Studio and re-opening it will do the trick without having to do a full Visual Studio restart.
I tried to solve an issue like this one yesterday. I had e pre-compiled dll (project name ie: MyHtmlHelpers) containing helpers and lot of other classes.
I had the assembly referenced in the web project and the all "standard"-helpers showed up in intellisense but, even though I added the namespace to both web.config in the root and in the views-folder nothing worked. When running the project helpers works, but not in intellisense.
I added a new class and wrote a new html helper inside the web project, added the namespace to web.config. And that worked.
After some hours add tried my last card, adding the MyHtmlHelpers-project to the same solution as my webproject. That did the trick. I diden't change anything in the configs just added the project to the same solution and changed the reference to point at the project insted of the compiled dll.
Isen't that strange? A VS-bug?
I found that i was adding the reference to the wrong web.config. It's not the main config but the web.config in the views directory...
So now I will show you the steps
1.Create or open an existing class library project (if you open an existing one be sure to remove the MVC5 nuget package)
2.Add the MVC (5.0) nuget package (
right click project in solution explorer -> Manage NuGet Packages -> search for MVC and install “Microsoft ASP.NET MVC”)
3.Close any and all open .cshtml files
4.Right click project -> Properties -> Build -> change Output path to your project “bin/”
5.Add the following minimal Web.config to the root of your class library project
( the web config file is solely needed for intellisense. Configuration (via Web.config)
should be done in the WebApplication hosting your ClassLibrary assembly)
6.Clean and Build the solution.
7.Open cshtml file and try now :)
I found that if it still doesn't work, you may need to go to the properties of the custom class and change the build action from "content" to "compile". That resolved it for me.
I try all of this solutions, one more thing which i didnt find is that in root web.config i must change webpages:Version from 2.0.0.0 to 3.0.0.0.
Open and close all .cshtml files and it's worked.
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />

MEF and Razor Views inside Class Library

I have a composite ASP .NET MVC 3 Razor application using MEF. Everything goes fine if I am to deploy plugins as DLL files and views (CSHTML) under the regular Views folder from the application. But this is not very clean and it won't be a real plugin if I don't place views as embedded resources within the DLL files (along with both controllers and models).
I've followed many articles (most of them are outdated). In fact there is one quite good one here on Stack Overflow: Controllers and Views inside a Class Library
I've also checked docs for VirtualPathProvider and I've been able to build a custom one that finds the file within the assembly and loads it perfectly (or at least gets the stream to it). For this I've followed the VirtualPathProvider documentation on MSDN.
There is also an implementation for VirtualFile but not yet for VirtualDirectory.
Here is the problem. I'm working with Razor views. I do know that they need config specs from the web.config file for Razor to build them. But if I embed them within the DLL this config is simply lost.
I wonder if that's why I keep getting the error:
The view at '~/Plugins/CRM.Web.Views.CRM.Index.cshtml' must derive
from WebViewPage, or WebViewPage.
Maybe I just need to add some code to make it work? Any ideas?
My preferred way to embed Razor Views in a Class Library is to copy them into the MVC website's Views/Areas folders with a post build event. Custom view locations can be specified if you override the ViewEngine or VirtualPathProvider.
The tricky part for me was getting intellisense to work in these View Class libraries. First, you must add a Web.Config to your View assembly. Note that you don't have to actually include it in your assembly. It only has to be in the assembly root directory (or views folder). Here is an example. Regard the important Assemblies/Compilation section.
<?xml version="1.0"?>
<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" />
</namespaces>
</pages>
</system.web.webPages.razor>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<compilation targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<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" />
</assemblies>
</compilation>
<httpHandlers>
<add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/>
</httpHandlers>
<!--
Enabling request validation in view pages would cause validation to occur
after the input has already been processed by the controller. By default
MVC performs request validation before a controller processes the input.
To change this behavior apply the ValidateInputAttribute to a
controller or action.
-->
<pages
validateRequest="false"
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<controls>
<add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
</controls>
</pages>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="BlockViewHandler"/>
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
</handlers>
</system.webServer>
</configuration>
Next, you need to modify your class library's vbproj file so that all OutputPath elements point to 'bin\' instead of 'Debug\bin\' or 'Release\bin\'. This is the main difference I found between class libraries and ASP.Net web project types that can cause intellisense bugs.
If you still recieve your must inherits error, consider using #Inherits System.Web.Mvc.WebViewPage in your views. If you are not copying your views into your website project, you may be loading them from Embedded Resources using a custom ViewEngine / VirtualPathProvider. If that is the case, you definately need the Inherits so Razor knows what your view base class is unfortunately.
Good luck.
You might take a look at the following blog post.
Hossam,
The post you're talking about is what Darin has already suggested. The main down side to that approach is using the custom MvcRazorClassGenerator compiler to convert the CSHTML view files in to class files. To do so you have to set every CSHTML view in your project to Content and set the Custom Tool to MvcRazorClassGenerator.
I can't speak for LordALMMa but I did download the compiler source and gave it a shot and it doesn't exactly work the way I was hoping.
My other approach was to include the CSHTML files as Embeded Resources in the external DLL, read in the raw contents of the file and execute the view as a string (See the RazorEngine on CodeProject for an example: http://razorengine.codeplex.com/)
I didn't want to fully depend on the RazorEngine in an enterprise application because I don't know how well it is compatiable with all of the Razor syntax so I gave up on that for now.
I'm coming from a prototype I built in ASP.NET MVC 2.0 that is a multi-tennant application. On a server farm we have one instance of an application running where all clients share the same code base. In my MVC 2.0 prototype I was able to determine what "client" the request was being made for, check for a custom controller that over-rides the base (for customizations of the core code) and also check for custom views (for customizations of the core view). What this does is allow us to deploy a "plugin" per say for each client. The software detects if the client has a custom controller that matches the request as well as a custom action that matches and if it does, it uses the customized controller/action instead.
When I started migrating my prototype to MVC 3 I ran in to the same problem as LordALMMa, the error "The view at '...Index.cshtml' must derive from WebViewPage, or WebViewPage". I'll look in to placing "#inherits System.Web.Mvc.WebViewPage" on my CSHTML views and see if that gets me any closer to getting it to work.
Since I have a working MVC 2.0 prototype using MVC 3 Razor is not a top priority and I don't waste a ton of time on it. I'm sure I can port the MVC 2.0 to MVC 3.0 using the WebForms engine if we need to leverage the 4.0 Framework.
Hey I suspect you have good reasons for wanting views inside DLLs. However also consider that it is an unusual way of packaging everything into one entity.
If you are developing a plugin, these days people opt for packaging in the NUGET format, which also solves your kind of problem among other things. It has a .nupkg structure which is also one way of distributing plugins as packages and libraries.
Another solution which communities generally follow is (if they do not want something as elaborate as nuget) they code up the plugin DLLs such that, it does not use view engines like razor, instead outputs HTML all by itself using the old primitive way of Response.Write and thus become independent of cshtml files. If you still want to use cshtml - see this blog entry for precompiling those into classes.

ASP.NET MVC Beta 1 - where is Html.RenderPartial?

I'm just in the process of upgrading my Preview 5 application to Beta 1, and I'm nearly there save for this one error when trying to render a control:
'System.Web.Mvc.HtmlHelper' does not
contain a definition for
'RenderPartial' and no extension
method 'RenderPartial' accepting a
first argument of type
'System.Web.Mvc.HtmlHelper' could be
found (are you missing a using
directive or an assembly reference?)
My markup (in the .aspx View Content Page) is:
<% Html.RenderPartial("Controls/UserForm", ViewData); %>
I've tried using Microsoft.Web.Mvc but to no avail. Does anyone know where Html.RenderPartial has gone, or what alternative I could use?
And also don't forget to add namespaces like below to the web config, I think preview 5 default web.config does not have System.Web.Mvc.Html in it:
<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="System.Linq"/>
<add namespace="System.Collections.Generic"/>
</namespaces>
Now fixed - the conflict was a difference in Web.config requirements between Preview 5 and Beta 1. The following needs to be added into the system.web compilation assemblies node:
<add assembly="System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
After this change, all of my old HtmlHelper methods magically came back!
In addition to adding the assembly reference I also had to add the line
<add namespace="System.Web.Mvc.Html"/>"
to the pages/namespaces section in web.config file.

Resources