确保所有* .cshtml文件都设置为"内容"用于构建行动

时间:2015-01-14 23:17:58

标签: razor visual-studio-2013 msbuild asp.net-mvc-5 webdeploy

当我复制粘贴*.cshtml文件时,Visual Studio因某些原因将这些文件上的Build Action设置为“无”: Comments.cshtml is set to be "None" on Build Action

当您在本地工作时,无法检测到,因为文件存在。但是,当您通过WebDeploy进行部署时,Build Action上标记为“None”的文件不会打包。因此,我在服务器上获得了非工作应用程序。

问题:是否有办法自动检测此类事件并阻止?

4 个答案:

答案 0 :(得分:30)

您可以使用小片段扩展.csproj,当“无”组中的项目具有扩展名.cshtml时,该片段会生成警告。该片段将是:

<Target Name="EnsureContentOnViews" BeforeTargets="BeforeBuild">
  <ItemGroup>
    <Filtered Include="@(None)" Condition="'%(Extension)' == '.cshtml'" />
  </ItemGroup>
  <Warning 
    Condition="'@(Filtered)'!=''"
    Code="CSHTML" 
    File="$(MSBuildProjectDirectory)\%(Filtered.Identity)" 
    Text="View is not set to [BuildAction:Content]"
  />
</Target>

如果您看到其他构建操作(如EmbeddedResource),则可以将它们添加到Filtered项目定义中。

如果您想要更高级的检测,您需要实际解析适合此Xpath的任何项目的项目文件//ItemGroup/*[not(self::Content)]/@Include

<Target Name="EnsureContentOnViewsXML" BeforeTargets="BeforeBuild">
  <XmlPeek XmlInputPath="$(MSBuildProjectFile)" Namespaces="&lt;Namespace Prefix='msb' Uri='schemas.microsoft.com/developer/msbuild/2003'/&gt;"; Query="/msb:Project/msb:ItemGroup/*[not(self::msb:EmbeddedResource)]/@Include">
    <Output TaskParameter="Result" ItemName="AllItems" />
  </XmlPeek>

  <!-- MsBuild uses XPath 1.0 which doesn't have the 'ends-with' or 'matches' function. -->
  <ItemGroup>
    <Filtered Include="@(AllItems)" Condition="'%(Extension)' == '.cshtml'" />
  </ItemGroup>

  <Warning 
    Code="CSHTML" 
    File="$(MSBuildProjectDirectory)\%(Filtered.Identity)" 
    Text="View is not set to [BuildAction:Content]"
    Condition="'@(Filtered)'!=''"
  />
</Target>

您也可以使用<Warning ...>

代替<Error ...>

您需要手动将其中一个片段放入项目文件中:

enter image description here

答案 1 :(得分:4)

谢谢jessehouwing让我开始吧!我喜欢你的解决方案,并投了赞成票。我遇到了一点麻烦,结果如下:

<Target Name="EnsureContentOnViews" BeforeTargets="BeforeBuild">
    <ItemGroup>
      <Filtered Include="@(None)" Condition="'%(Extension)' == '.cshtml'" />
    </ItemGroup>
    <Error Condition="'@(Filtered)'!=''" Code="CSHTML" File="%(Filtered.Filename)" Text="Not set to [BuildAction:Content]: Identity: %(Filtered.Identity)" />
</Target>

在csproj文件中的</Project>标记之前。

答案 2 :(得分:3)

嗯,@ jessehouwing肯定对我有用!因此,修复程序在我的.csproj文件中保持良好状态:)....只是,我只是仔细检查了一下,由于另一个开发人员或其他东西的合并,看起来这个好的代码段在上个月某处消失了。 (真实的故事)

NPM替代

无论如何,我想提一下我为此创建的NPM模块check-vs-includes。安装Node的开发人员特别方便(如果不安装,那么你可能应该:)。

我在每次部署之前手动运行检查,而不是在每次构建时运行。但是由于合并,它不太可能从你的.csproj文件中消失(不被注意)。

使用这个NPM软件包的主要优点是,除了检查Build Action NONE之外,它还会检查项目中根本不包含的文件。因为当您使用Visual Studio的Web部署时,这也可能导致(微妙但令人讨厌的)错误。如果出现以下情况,实际上很可 1)您的团队中有1名非VS开发人员,或者 2)由于.csproj文件的合并(通常有合并问题)。

查看NPM页面以获取说明。但是在一个简单的例子下面,假设你使用Node和Gulp:

简单示例

  1. 安装节点模块

      

    npm i check-vs-includes

  2. gulpfile.js添加任务:

  3.      var checkVSIncludes = require('check-vs-includes');
    
         ...
    
         gulp.task('checkVSIncludes', function() {
            checkVSIncludes(['/Views/**/*.cshtml', '/app/**/*.js']);
         });
    
    1. 在项目文件夹中运行检查(例如,.csproj文件所在的位置)
        

      gulp checkVSIncludes

答案 3 :(得分:0)

我建议实现自定义构建任务。在msbuild / tfs脚本中的prebuild上调用它。 如果存在包含build action none的cshtml包含文件,则自定义构建任务应该检查.scproj文件。这样就退出返回一个非零的int值。