Razor 确保所有的*.cshtml文件都设置为";内容“;用于构建操作

Razor 确保所有的*.cshtml文件都设置为";内容“;用于构建操作,razor,visual-studio-2013,msbuild,asp.net-mvc-5,webdeploy,Razor,Visual Studio 2013,Msbuild,Asp.net Mvc 5,Webdeploy,有几次,当我复制粘贴*.cshtml文件时,Visual Studio出于某种原因将这些文件上的生成操作设置为“无”: 当您在本地工作时,这是不可能检测到的,因为文件存在。但当您通过WebDeploy部署时,在构建操作上标记为“无”的文件不会打包。因此,我在服务器上得到了不工作的应用程序 问题:是否有一种方法可以自动检测并防止此类事件发生?我建议实施自定义生成任务。在msbuild/tfs脚本中的预构建时调用它。 自定义生成任务应该只检查.scproj文件,如果有包含cshtml的包含文件且生

有几次,当我复制粘贴
*.cshtml
文件时,Visual Studio出于某种原因将这些文件上的
生成操作设置为“无”:

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


问题:是否有一种方法可以自动检测并防止此类事件发生?

我建议实施自定义生成任务。在msbuild/tfs脚本中的预构建时调用它。
自定义生成任务应该只检查.scproj文件,如果有包含cshtml的包含文件且生成操作为“无”。当然,只需返回一个非零的int值即可退出。

您可以使用一个小片段扩展
.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>
除了
之外,您还可以使用

您需要在项目文件中手动放置以下代码段之一:


好吧,@jessehouwing肯定对我有用!因此,修复程序很好地保存在我的
.csproj
文件中:)。。。。只是,我只是仔细检查了一下,就好像上个月由于另一个开发人员的合并或其他什么原因,那个漂亮的代码片段消失了。。(真实故事)

NPM替代方案 无论如何,我想提到我为此创建的NPM模块。这对于已经安装的开发人员来说尤其方便(如果您没有安装,那么您可能应该:)

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

然而,使用这个NPM包的主要优点是,除了检查Build Action NONE之外,它还检查项目中根本不包含的文件。因为在使用VisualStudio的Web Deploy时,这也会导致(微妙但令人讨厌的)错误。如果: 1) 您的团队中有1名非VS开发人员,或者 2) 由于.csproj文件的合并(通常存在合并问题)

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

简单例子
  • 安装节点模块

    npm我检查vs包括

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

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


  • 谢谢你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文件中我的
    标记之前。

    那么这个构建操作是如何实现的呢?这很有效,感谢您朝着正确的方向推进。我只需要将
    条件=“@(过滤)”!=“code>添加到
    伟大的答案中!我的问题和trailmax一样。反馈:第二个选项(带有XmlPeek的选项)对我不起作用(没有显示警告),但第一个选项工作得很好。谢谢我真的很想使用XmlPeek方法,因为它更整洁,但正如其他人所说,遇到了同样的问题,没有匹配任何元素。发现这是由于命名空间引起的<代码>
    Typo在上述代码中,“EmbeddedResource”上还需要有一个命名空间:
    XmlInputPath=“$(MSBuildProjectFile)”namespace=“命名空间前缀='msb'Uri=”http://schemas.microsoft.com/developer/msbuild/2003“/”Query=“/msb:Project/msb:ItemGroup/*[not(self::msb:EmbeddedResource)]/@Include”>
    精彩片段。谢谢分享这颗金色的MSBuild金块!我使用VisualStudio的扩展来运行检查,而不是第3点中的命令。如果在安装点1后添加
    --save dev
    ,那么您的同事也可以从自动检查中获益。(他们必须运行
    npm install
    一次,才能获得此开发依赖项)。对于仍在使用Visual Studio快速版(不允许安装扩展)的读者,请立即升级到Visual Studio 2013社区版(该版本有,而且也是免费的:)。请投票给其他人一篇好的文章。但我不使用node或gulp,所以对我来说非常无用。 var checkVSIncludes = require('check-vs-includes'); ... gulp.task('checkVSIncludes', function() { checkVSIncludes(['/Views/**/*.cshtml', '/app/**/*.js']); });
    <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>