MVC 4 - 在类库中使用Razor视图

6

我想让你翻译一个关于it技术的内容。要翻译的是如何在类库项目中使用MVC 4 Razor View。我已经在类库根目录和views文件夹中添加了Web.Config文件,但是我的view中的@model仍然无法识别。

我还将Microsoft.AspNet.Mvc包添加到了项目中。有人知道如何解决这个问题吗?

以下是我的Web.Config文件:

1- Views文件夹

<?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:Enabled" value="false" />
  </appSettings>

  <system.web>
    <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=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
        pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
        userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <controls>
        <add assembly="System.Web.Mvc, Version=4.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>

2 - 根目录

<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
  <appSettings>
    <add key="webpages:Version" value="2.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="PreserveLoginUrl" value="true" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  </appSettings>
  <system.web>
    <httpRuntime targetFramework="4.5" />
    <compilation debug="true" targetFramework="4.5" />
    <pages>
      <namespaces>
        <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.Routing" />
        <add namespace="System.Web.WebPages" />
      </namespaces>
    </pages>
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <handlers>
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>
</configuration>

有人知道我缺少什么吗?

谢谢,

Miguel


2
你的意思是你想在类库中运行一个视图?这没有意义 - 我认为你的问题/目标不是很清楚。 - naspinski
2个回答

3

原来,最简单的解决方案是将其创建为Web应用程序,但这可能不适合所有人。

第一次尝试

我自己也有一个类库,想在其中创建一些控件,但我希望拥有一个工作的Razor视图,并获得完整的智能支持。其中的诀窍是:

  1. 添加引用(针对MVC)
  2. 在ProjectGUID后通过文本编辑方式将ProjectTypeGuids添加到.csproj中:<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
  3. 添加.cshtml Razor视图文件(在下一部分之前它不会正常工作)
  4. 添加Web.Config文件(查看您的View文件夹web.config)
  5. 项目属性构建输出路径更改为bin\(而不是bin\Debug
  6. 清理并生成解决方案

几乎可以实现(评论提到了Bin文件夹问题): https://conficient.wordpress.com/2013/11/27/asp-net-razor-views-in-class-libraries/

另一个包含Bin的指南: http://thetoeb.de/2014/01/05/enabling-mvc5-intellisense-in-a-classlibrary-project/

但这些只有在您避免使用真正的ASP.Net MVC网站时才有意义。因此,现在您需要运行它的东西......有选择,但超出了本条目的范围。


即将完成

如果您只想编译视图,并希望许多其他真实的ASP.Net MVC项目将其重新使用为项目,则可以使用Razor Generator。但是即使在这里,您也可能不想将项目创建为类库,因为这样做并不好玩...

  1. 安装Razor Generator的VS扩展程序
  2. 添加新的类库项目
  3. 为您的库添加RazorGenerator.Mvc NuGet包
  4. 为您的库添加PrecompiledMvcViewEngineContrib NuGet包
  5. 创建一个Views文件夹和一个控制器命名的文件夹,用于您希望以此访问的虚拟路径
  6. 移动任何视图到该新的 \Views\ControllerName\ 文件夹
  7. 将所有这些库视图设置为Custom Tool RazorGenerator(右键单击视图属性)
  8. 从您的真实ASP.Net MVC Web应用程序中添加对您的库的引用

从那以后,我经常还会遇到问题。如果我不添加Microsoft.CodeDom.Providers.DotNetCompilerPlatform nuget包,我将被困在C# 2.0中。该nuget包适用于4.5版本,因此对于4.6.x版本,可以修改app.config中的新代码段。

  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701">
        <providerOption name="CompilerVersion" value="v4.0"/>
      </compiler>
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+"/>
    </compilers>
  </system.codedom>

现在,您可以将“var”用作隐式类型和其他现代C#功能。
接下来,我遇到了一个问题,即尽管已经引用了System.Linq扩展方法,但找不到它...生活并不完美...如果您想要拥有一切...但如果这是您想要更深入探索的路径,那就是个开始。

最简单的方案

但是,如果你遵循Razor Generator团队的建议,并且在常规MVC Web应用程序上安装Razor Generator(只需将你的"library"创建为一个),那么几乎不需要进行任何工作......

  1. 拥有一个真正的MVC ASP.Net主站点
  2. 创建一个新的MVC ASP.Net网站,作为你的“库”,这样你就不必那么麻烦了
  3. 在“库”中安装Nuget Package for RazorGenerator.MVC
  4. 在“库”中安装Nuget Package for PrecompiledMvcViewEngineContrib
  5. 将视图移动到库中类似的结构,并标记为Custom Tool RazorGenerator
  6. 从主站点引用你的“库”,这样就能以更少的麻烦完成所有工作了。

美妙的事情在于,你引用的“库”有App Start代码,在你的主应用程序启动时运行,并注册了PreCompiledViewEngine,它知道虚拟路径,而不仅仅是物理路径。然后,你的RazorGenerator Custom Tool视图将定义它们的虚拟路径,当视图路径被解析时,就可以找到它们。


关于该主题的良好参考资料: https://www.c-sharpcorner.com/UploadFile/97fc7a/article-precompiled-razor-view-using-razorgenerator-mvc-and/


如果你正在这条路上,可能不久之后你就想以某种方式赋予Razor基本页面类型更多的权力。可以通过web.config <pages pageBaseType="System.Web.Mvc.WebViewPage"> 更改页面基本类型。 https://haacked.com/archive/2011/02/21/changing-base-type-of-a-razor-view.aspx/ - Greg

2

为了使智能感知正常工作,您的项目必须是Web应用程序。Web应用程序只是一个特殊的类库。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接