可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
We have a modular architecture where we have some views (cshtml) files in a separate project (class library). How can we get the syntax highlighting and autocomplete to work when the project isn't an MVC project?
Please note that the class library has controllers, views, models etc. It just doesn't have the web.config, global.asax, etc that a normal mvc project would have.
The intellisense works for everything but the so important model:
With MVC3 RTM, if you hover over the Model, you can now get a better error message:
C:\...\Index.cshtml: ASP.NET runtime
error: There is no build provider
registered for the extension
'.cshtml'. You can register one in the
<compilation><buildProviders>
section in the machine.config or
web.config. Make sure is has a
BuildProviderAppliesToAttribute
attribute which includes the value
'Web' or 'All'.
So I added this:
<compilation>
<assemblies>
<add assembly="System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</assemblies>
<buildProviders>
<add
extension=".cshtml"
type="System.Web.WebPages.Razor.RazorBuildProvider, System.Web.WebPages.Razor"/>
</buildProviders>
</compilation>
Then after adding the build provider, this error message appears:
C:\...\Index.cshtml: ASP.NET runtime
error: Could not load file or assembly
'System.Web.WebPages.Razor' or one of
its dependencies. The system cannot
find the file specified.
(C:\...\machine.config line 259)
回答1:
The webconfig from this post will work. I've copied it below (for posterity):
<?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>
<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" />
</assemblies>
</compilation>
</system.web>
</configuration>
回答2:
For Visual Studio 2012/ASP.NET MVC 4, you need to update the assembly versions and add <add key="webpages:Version" value="2.0.0.0" />
to appSettings
. Here's what my Web.config looks like:
<?xml version="1.0"?>
<configuration>
<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>
<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>
<appSettings>
<add key="webpages:Version" value="2.0.0.0" />
</appSettings>
<system.web>
<compilation targetFramework="4.5">
<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=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</assemblies>
</compilation>
</system.web>
</configuration>
回答3:
I have followed Jammer's suggestion and am documenting what I believe is the minimal set of actions to get a project suitable for serving as an ASP.NET MVC4 class library project. This was done in Visual Studio 2012 Update 4, and was targeting VB.Net. I may later include documentation for doing something similar in Visual Studio 2013 if I get a chance. Here are the actions I took:
- Create a new blank MVC4 project with a separate directory for the solution (so you can clearly see that the
packages
directory with updated versions of reference files is part of the project).
- Add a dummy controller, view and model to test it (which entailed copying the output DLL and view to another web application after building the class library).
- Delete the following files from the project:
- The whole
App_Start
folder
- The whole
App_Data
folder and any other empty folders (my Mercurial history didn't make this visible so I'm going from memory).
Global.asax
Global.asax.vb
- The
Web.config
file in the root and the dependent Web.Debug.config
and Web.Release.config
files. (Do not delete Web.config
from the Views folder.)
- Delete the following sections from the
Web.config
file in the Views folder:
appSettings
system.web
system.webServer
- You may also delete lines
<add namespace="System.Web.Mvc.Ajax" />
and <add namespace="System.Web.Routing" />
- Remove the following references from the project (* starred references were version-specific references that went into the
packages
directory and have Copy Local
and Specific Version
set to True
).
System.Web.Entity
System.Web.ApplicationServices
System.ComponentModel.DataAnnotations
System.Data.DataSetExtensions
System.Web.Extensions
System.Web.Extensions.Design
System.Xml.Linq
System.Web.Abstractions
System.Web.Routing
System.Configuration
System.Web.Services
System.EnterpriseServices
Microsoft.Web.Infrastructure
(1.0.0.0) *
Microsoft.Web.Mvc.FixedDisplayModes
(1.0.0) *
Newtonsoft.Json
(4.5.11) *
System.Net.Http
(2.0.20710.0) *
System.Net.Http.Formatting
(4.0.20710.0) *
System.Net.Http.WebRequest
(2.0.20710.0) *
System.Web.Helpers
(2.0.20710.0) *
System.Web.Http
(4.0.20710.0) *
System.Web.Http.WebHost
(4.0.20710.0) *
- Remove the following project-wide Imports from the project settings:
System.Xml.Linq
System.Collections.Specialized
System.Configuration
System.Web.Caching
System.Web.Mvc.Ajax
System.Web.Routing
System.Web.SessionState
System.Web.Security
System.Web.Profile
System.Web.UI
System.Web.UI.WebControls
System.Web.UI.WebControls.WebParts
System.Web.UI.HtmlControls
- Remove the following from
packages.config
:
- <package id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.0" targetFramework="net40" />
- <package id="Microsoft.AspNet.WebApi" version="4.0.20710.0" targetFramework="net40" />
- <package id="Microsoft.AspNet.WebApi.Client" version="4.0.20710.0" targetFramework="net40" />
- <package id="Microsoft.AspNet.WebApi.Core" version="4.0.20710.0" targetFramework="net40" />
- <package id="Microsoft.AspNet.WebApi.WebHost" version="4.0.20710.0" targetFramework="net40" />
- <package id="Microsoft.Net.Http" version="2.0.20710.0" targetFramework="net40" />
- <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net40" />
- <package id="Newtonsoft.Json" version="4.5.11" targetFramework="net40" />
- Delete the following sub-directories from the packages folder:
- Microsoft.AspNet.Mvc.FixedDisplayModes.1.0.0
- Microsoft.AspNet.WebApi.4.0.20710.0
- Microsoft.AspNet.WebApi.Client.4.0.20710.0
- Microsoft.AspNet.WebApi.Core.4.0.20710.0
- Microsoft.AspNet.WebApi.WebHost.4.0.20710.0
- Microsoft.Net.Http.2.0.20710.0
- Microsoft.Web.Infrastructure.1.0.0.0
- Newtonsoft.Json.4.5.11
This leaves me with the following:
- A VB.Net class library project targeting .NET Framework 4 (although I had intended this to be 4.5 - I think either works).
- The following non-default .NET references (starred references must have
Copy Local
and Specific Version
set to True
):
- System.Web
- packages\Microsoft.AspNet.Mvc.4.0.20710.0\lib\net40\System.Web.Mvc.dll *
- packages\Microsoft.AspNet.Razor.2.0.20715.0\lib\net40\System.Web.Razor.dll *
- packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.dll *
- packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Deployment.dll *
- packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Razor.dll *
- The following non-default imports:
- System.Web
- System.Web.Mvc
- System.Web.Mvc.Html
- The following project files/structure:
Controllers
folder containing CustomUIController.vb
Models
folder containing CustomUIModel.vb
Views
folder containing CustomUI
folder, containing Index.vbhtml
Web.config
file in the Views folder. See below for content.
packages.config
file in the root of the project. See below for content.
The contents of my files are as follows:
Web.config
<?xml version="1.0"?>
<configuration>
<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>
<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.Html" />
</namespaces>
</pages>
</system.web.webPages.razor>
</configuration>
packages.config
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.Mvc" version="4.0.20710.0" targetFramework="net40" />
<package id="Microsoft.AspNet.Razor" version="2.0.20715.0" targetFramework="net40" />
<package id="Microsoft.AspNet.WebPages" version="2.0.20710.0" targetFramework="net40" />
</packages>
CustomUIController.vb
Imports System.Web.Mvc
Public Class CustomUIController
Inherits Controller
Public Function Index() As ActionResult
Return View()
End Function
End Class
CustomUIModel.vb
Public Class CustomUIModel
Public Property Name As String
Public Property Value As Decimal
End Class
Index.vbhtml
@ModelType CustomTemplate.CustomUIModel
@Html.LabelFor(Function(m) m.Name)
At this point I am able to work with Intellisense assisting me in the .vbhtml views and the .vb classes, build the project, then copy just the views to the primary application's deployed Views
folder (in the appropriate sub-directory), and the project's primary output DLL to the primary application's deployed bin
directory (the dependent DLL files are already there).
Edit:
After following the process on another system to validate it and how it works for .NET 4.5 and VS 2013, I have noticed the following:
- I think I neglected to mention that the reference to
System.Web.DynamicData
can be removed.
- In VS 2013 and/or .NET 4.5, some versions change:
- packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll
- packages\Microsoft.AspNet.Razor.2.0.30506.0\lib\net40\System.Web.Razor.dll
- packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.dll
- packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Deployment.dll
- packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Razor.dll
- I don't know if I made a strong enough point of it above, but the references to private (Copy Local) DLLs do have to be set to Copy Local, and/or do have to use the version provided in the packages folder when creating a project from the MVC4 template. I don't know why, but the .NET standard versions (non-private) don't seem to work, as far as Intellisense is concerned at least.
- Best way to check if things are still "OK" as far as the IDE is concerned is to close the solution, delete the
bin
and obj
folders in the custom project's output, re-load the solution, put the cursor on LabelFor
in the Index.vbhtml file, and press the F12 key to see if it takes you to the Object Browser.
Because of the new versions, the packages file is different:
Packages.config
<packages>
<package id="Microsoft.AspNet.Mvc" version="4.0.30506.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="2.0.30506.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="2.0.30506.0" targetFramework="net45" />
</packages>
回答4:
Alright, this is a longshot, but I ran across the same problem. Are you using JetBrains Resharper?
Resharper overrides VS's intellisense engine but it doesn't understand Razor syntax. You simply have to tell VS to rely on its own intellisense rather than Resharper's.
In VS2010, go Resharper - Options - Intellisense - General. Then check the Visual Studio radio button.
Worked great for me.
回答5:
None of the solutions I could find online or on SO fixed this for me.
May seem like a sledgehammer to crack a nut but I created an MVC 4 application project instead of a class library and ripped out everything I didn't need. Intellisense and @model
working fine.