【问题标题】:Make sure all *.cshtml files are set to be "Content" for Build Action确保所有 *.cshtml 文件都设置为构建操作的“内容”
【发布时间】:2015-03-13 07:19:30
【问题描述】:

当我复制粘贴 *.cshtml 文件时,Visual Studio 出于某种原因将这些文件上的 Build Action 设置为“无”:

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

问题:有没有办法自动检测并防止此类事件的发生?

【问题讨论】:

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


    【解决方案1】:

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

    <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),您可以将它们添加到过滤项定义中。

    如果您想要更高级的检测,您需要实际解析项目文件以查找适合此 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>
    

    你也可以使用&lt;Error ...&gt;代替&lt;Warning ...&gt;

    您需要手动将这些 sn-ps 之一放入您的项目文件中:

    【讨论】:

    • 成功了,感谢您朝着正确的方向前进。只有我必须将Condition="'@(Filtered)'!=''" 添加到&lt;Warning - 一直发出警告,即使没有不正确的文件
    • 很好的答案!我遇到了和 trailmax 一样的问题。反馈:第二个选项(带有 XmlPeek 的那个)对我不起作用(不显示警告),但第一个选项完美。谢谢!
    • 我真的很想使用 XmlPeek 方法,因为它更整洁,但正如其他人所说,遇到了同样的问题,没有元素被匹配。发现这是由于命名空间。 &lt;XmlPeek XmlInputPath="$(MSBuildProjectFile)" Namespaces="&amp;lt;Namespace Prefix='msb' Uri='http://schemas.microsoft.com/developer/msbuild/2003'/&amp;gt;" Query="/msb:Project/msb:ItemGroup/*[not(self::EmbeddedResource)]/@Include"&gt;
    • 上述代码中的错字,'EmbeddedResource' 上也需要有一个命名空间:XmlInputPath="$(MSBuildProjectFile)" Namespaces="&amp;lt;Namespace Prefix='msb' Uri='http://schemas.microsoft.com/developer/msbuild/2003'/&amp;gt;" Query="/msb:Project/msb:ItemGroup/*[not(self::msb:EmbeddedResource)]/@Include"&gt;
    • 精彩的 sn-p。感谢您分享这个金色的 MSBuild 金块!
    【解决方案2】:

    感谢 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 文件中我的 &lt;/Project&gt; 标记之前。

    【讨论】:

      【解决方案3】:

      嗯,@jessehouwing 肯定对我有用!因此,该修复程序很好地保留在我的.csproj 文件中:).... 只是,我只是仔细检查了一下,看起来那个不错的 sn-p 在上个月的某个地方消失了,因为另一个开发人员或其他东西的合并。 .(真实故事)

      NPM 替代方案

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

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

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

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

      简单示例

      1. 安装节点模块

        npm i check-vs-includes

      2. 将任务添加到您的gulpfile.js

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

        gulp checkVSIncludes

      【讨论】:

      • 我使用 Visual Studio 的 Task Runner Explorer 扩展来运行检查,而不是第 3 点中的命令。如果在第 1 点安装后添加 --save-dev,那么您的同事也可以从中受益这种自动检查。 (他们必须运行一次npm install,才能获得这种开发依赖)。对于仍在使用 Visual Studio Express 版本(不允许安装扩展)的读者,现在升级到 Visual Studio 2013 社区版(可以而且也是免费的:))。
      • 为其他人的好文章点赞。但是我没有使用 node 或 gulp,所以对我来说毫无用处。
      【解决方案4】:

      我建议实施自定义构建任务。在你的 msbuild/tfs 脚本中调用它。 自定义构建任务应该只检查 .scproj 文件,如果存在构建操作无的 cshtml 包含文件。所以只是退出返回一个非零的 int 值。

      【讨论】:

      • 那么这个构建操作是如何准确实现的?
      猜你喜欢
      • 1970-01-01
      • 2011-05-12
      • 2018-04-14
      • 1970-01-01
      • 1970-01-01
      • 2017-05-23
      • 1970-01-01
      • 1970-01-01
      • 2013-02-27
      相关资源
      最近更新 更多