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>