在ASP.NET MVC中编译视图

589

我想要一个msbuild任务来编译视图,这样我就可以在编译时看到是否有编译时错误。 有任何建议吗?


1
我不知道你在使用什么视图引擎,但如果你正在使用Razor,你可能想看看我的博客文章:<a href="http://www.chrisvandesteeg.nl/2010/11/22/embedding-pre-compiled-razor-views-in-your-dll/">将你的asp.net mvc Razor视图编译成单独的dll</a>。这段代码也可以用于其他视图引擎,但我还没有进行过测试。 - Chris van de Steeg
9个回答

592

来自 RC1 的自述文档(Google 不可索引)

ASP.NET 编译器后置构建步骤

目前,在视图文件中出现的错误直到运行时才被检测到。为了让你在编译时便能检测到这些错误,ASP.NET MVC 项目现在包含了一个 MvcBuildViews 属性,默认情况下是禁用的。要启用此属性,请打开项目文件并将 MvcBuildViews 属性设置为 true,如以下示例所示:

<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <MvcBuildViews>true</MvcBuildViews>
  </PropertyGroup>

注意:启用此功能会增加构建时间的开销。

您可以通过执行以下步骤,将使用先前版本的 MVC 创建的项目更新为包括视图构建时验证:

  1. 在文本编辑器中打开项目文件。
  2. 在最上层的<PropertyGroup>元素下添加以下元素: <MvcBuildViews>true</MvcBuildViews>
  3. 在项目文件末尾取消注释 <Target Name="AfterBuild"> 元素,并将其修改为以下内容:
<Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
    <AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)\..\$(ProjectName)" />
</Target>

29
如果这个方法对你的项目不起作用,检查一下你的项目文件中是否有<MvcBuildViews>false</MvcBuildViews>。它会覆盖我在其上方添加的新<MvcBuildViews>元素。 - Adrian Grigore
3
@mxmissile: Scott Guthrie建议将Web Deployment Project添加到您的解决方案中,以在Web应用程序项目中获得此类支持:http://weblogs.asp.net/scottgu/archive/2006/09/22/Tip_2F00_Trick_3A00_-Optimizing-ASP.NET-2.0-Web-Project-Build-Performance-with-VS-2005.aspx - Zhaph - Ben Duguid
6
确保将 EnableUpdateable 设置为 false,否则视图不会被预编译。 <EnableUpdateable>false</EnableUpdateable> <MvcBuildViews>true</MvcBuildViews>(http://devcarl.posterous.com/dont-combine-enableupdateable-and-mvcbuildvie) - Carl Hörberg
62
为什么,为什么,为什么……没有建立包含或不包含视图的键盘快捷方式呢?微软,为什么? - dariol
2
这是添加到MVC工具的解决方案。https://dev59.com/jHRA5IYBdhLWcg3w_DHF#2670792 - lko
显示剩余4条评论

161

我个人会推荐使用RazorGenerator nuget包。这样,当你保存视图时,它们就会生成一个 .designer.cs 文件,在获取视图的编译时错误的同时,它们也会被预编译到程序集中(=更快的热启动),而且Resharper还提供了一些额外的帮助。

要使用这个方法,请在ASP.NET MVC项目中包含RazorGenerator nuget包,并在工具→扩展和更新项下安装“Razor Generator”扩展。

我们使用这个方法,每次编译的开销都要小得多。此外,我可能还会推荐使用RedGate的.NET Demon来进一步减少编译时间的影响。


1
有没有类似的解决方案适用于VS2012? - daniel
7
很遗憾它只支持C#,不支持VB.Net。 - Ed DeGagne
4
RazorGenerator可以在VS2012中使用。如果使用RazorGenerator.Mvc和RazorGenerator.MsBuild,则无需扩展名。请参阅stacktoheap.com上有关预编译Razor视图的博客文章。 - Jeroen K
2
这个能不能只用来查找错误,还是在部署应用程序时替换视图引擎? - niico
我已经安装了RazorGenerator NuGet包和Razor Generator扩展。我的项目没有任何更改。没有出现.designer.cs文件。我使用的是Visual Studio 2017。 - Michael Samteladze
显示剩余3条评论

54

你可以使用 aspnet_compiler 来实现此功能:

C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_compiler -v /Virtual/Application/Path/Or/Path/In/IIS/Metabase -p C:\Path\To\Your\WebProject -f -errorstack C:\Where\To\Put\Compiled\Site

其中"/Virtual/Application/Path/Or/Path/In/IIS/Metabase"是类似于"/MyApp"或"/lm/w3svc2/1/root/"这样的东西。

此外,MSDN上还有一个AspNetCompiler任务,展示了如何将aspnet_compiler与MSBuild集成:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="PrecompileWeb">
        <AspNetCompiler
            VirtualPath="/MyWebSite"
            PhysicalPath="c:\inetpub\wwwroot\MyWebSite\"
            TargetPath="c:\precompiledweb\MyWebSite\"
            Force="true"
            Debug="true"
        />
    </Target>
</Project>

5
这已经过时了,请见下面自 readme 文档中的摘录。 - JarrettV
1
另一个答案更详细地描述了项目任务,但aspnet_compiler部分仍然是正确的(并且在构建代理上非常有用)。 - mlhDev

28

此外,如果你使用 Resharper,你可以激活“解决方案宽度分析”,它可以检测出在 aspx 文件中可能存在的任何编译器错误。这就是我们所做的...


4
确实,它适用于aspx文件,但解决方案范围分析不包括ascx文件(用户控件)。 - mookid8000
3
我相信在 R#5 中是可以实现的,但对于大型项目来说它需要消耗大量的资源(即使在我的 16GB 家用电脑上也不值得使用)。 - Andrew
3
@Andrew / @mookid8000 -- R#还会检测编译器无法捕捉到的错误,例如缺少/不正确的视图和动作。使用R#会稍微减慢您的计算机速度(在具有4GB RAM和超线程CPU的大型项目中,我发现它很好),但我轻松地弥补了等待时间,并且最终在我的代码上操作更少,因为R#提供了更高级别的操作,可以批处理许多步骤,以手动完成相同任务所需的操作。你的项目一定很庞大! - Drew Noakes
5
对于大型项目来说,“让你的电脑慢一点”这个说法太轻描淡写了。我的构建机器有16GB的RAM和8个核心(2个Xeons),但它只是慢吞吞的。我有种感觉,R#并不适用于我们这样规模的项目...例如,我们的解决方案有约30个项目,几百万行代码和许多视图。我喜欢在我们小型项目上使用R#(例如,几个项目和不超过50个视图),但在我们的大型项目上,我们总是不得不关闭它。 - Beep beep
1
这个可能会起作用,但是请逃离!我打开它时认为我的解决方案很小,但它从未完成“分析”,并吃掉了我所有的内存和 CPU。花了我 15 分钟才恢复。 - emragins

15
下一个版本的ASP.NET MVC(大约在一月左右发布)应该会有MSBuild任务编译视图,因此您可能需要等待。
请查看公告

9

8

生成 > 运行代码分析

快捷键: Alt+F11

帮助我发现 Razor 错误。


2
我点赞了这个答案,因为这个快捷键确实暴露了一个Razor错误。但是后来我注意到,它似乎只在你在IDE中打开.cshtml文件时才起作用。 - Michael12345

3
使用Visual Studio的Productivity Power Tools免费)扩展会有所帮助。特别是Solution Error Visualizer功能。使用它,编译错误在解决方案资源管理器中以视觉方式标记(在找到错误的源文件中)。但出于某种原因,在代码的其他任何地方,此功能都无法正常工作。

对于MVC视图,任何编译时错误仍将在其各自的.cs文件中用红色下划线标出,但不会向上传播这些错误至解决方案资源管理器(甚至不在包含源文件中)。

感谢BlueClouds更正我的先前声明。

我刚刚在扩展的github项目上报告了这个问题


1
我尝试了Productivity Power Tools。但它的行为并不像这里所说的那样。Razor视图中有错误,但构建是成功的。视图没有被标记或用红色下划线标出,在解决方案资源管理器树中也没有任何标识。 - Blue Clouds
2
@BlueClouds:你说得对。我创建了一个示例项目,并在视图中添加了一个编译时错误。扩展将用红色下划线标出错误行,但不会在解决方案资源管理器中传播错误。我正在更正我在答案中所述的内容。我仍然将答案留在这里,因为它仍然有一定帮助,但确实不能有效地解决问题。 - Veverke

0
如果您在一个解决方案中有多个带有MVC视图的Web项目,并且有很多MVC视图,构建它们可能会使总构建时间翻倍。至少对我来说是这样的。
MSBuild有一个名为“增量构建”的功能,可以告诉MSBuild如果没有更改,则避免再次构建视图。
来自文档的引用如下:
“为了启用增量构建(仅构建以前未构建或过时的目标的构建),Microsoft Build Engine(MSBuild)可以将输入文件的时间戳与输出文件的时间戳进行比较,并确定是否跳过、构建或部分重新构建目标。”
我们只需要提供输入和输出。作为输入,我们可以使用我们的视图,而作为输出,我们可以在obj文件夹的某个地方生成一个空文件。
当运行Cleanup时,我们还需要记得清理输出文件。
以下代码可以实现这一点:
<PropertyGroup>
  <BuildDependsOn>
    $(BuildDependsOn);
    BuildMvcViews;
  </BuildDependsOn>

  <BuildMvcViewsCacheFile>$(IntermediateOutputPath)$(MSBuildProjectFile).BuildMvcViews.cache</BuildMvcViewsCacheFile>
</PropertyGroup>

<ItemGroup>
  <BuildMvcViewsInputs Include="$(ProjectDir)Views\**\*.cshtml"></BuildMvcViewsInputs>
</ItemGroup>

<Target Name="BuildMvcViews" Inputs="@(BuildMvcViewsInputs)" Outputs="$(BuildMvcViewsCacheFile)">
  <AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)" Condition="'@(BuildMvcViewsInputs)' != ''"/>
  <WriteLinesToFile
    File="$(BuildMvcViewsCacheFile)"
    Lines=""
    Overwrite="true"
    Condition="'@(BuildMvcViewsInputs)' != ''"/>
</Target>

<PropertyGroup>
  <CleanDependsOn>
    $(CleanDependsOn);
    CleanBuildMvcViewsCacheFile;
  </CleanDependsOn>
</PropertyGroup>

<Target Name="CleanBuildMvcViewsCacheFile">
  <Delete Files="$(BuildMvcViewsCacheFile)" />
</Target>

更多信息请参阅我的博客文章:https://www.bartlomiejmucha.com/en/blog/msbuild/how-to-optimize-build-times-for-mvc-views

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