Подтвердить что ты не робот

Убедитесь, что для всех файлов *.cshtml установлено значение "Содержимое" для действия сборки

Несколько раз, когда я копировал файлы *.cshtml, Visual Studio по какой-то причине устанавливает Build Action в эти файлы как "Нет": Comments.cshtml is set to be "None" on Build Action

Это невозможно обнаружить, когда вы работаете локально, потому что файлы присутствуют. Но при развертывании через WebDeploy файлы, помеченные как "Нет" в действии сборки, не упаковываются. В результате я получаю нерабочее приложение на сервере.

Вопрос: существует ли способ автоматического обнаружения таких случаев и предотвращения?

4b9b3361

Ответ 1

Вы можете расширить .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 item.

Если вам требуется более продвинутое обнаружение, вам необходимо проанализировать файлы проекта для любого элемента, который подходит для этого 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

Ответ 2

Хорошо, @jessehouwing, безусловно, сработал у меня! Итак, это исправление прекрасно сохранилось в моем файле .csproj:).... Только, я просто дважды проверял и выглядит так, как будто этот красивый снипп исчез где-то за последний месяц из-за слияния другого разработчика или чего-то еще.. ( истинная история)

Альтернатива NPM

В любом случае, я хотел бы упомянуть модуль NPM check-vs-includes, который я создал для этого. Особенно удобно для разработчиков, у которых Node установлен (и если вы этого не сделаете, то вам, вероятно, нужно:)).

Я запускаю проверку вручную перед каждым развертыванием, а не на каждой сборке. Но он вряд ли исчезнет (незаметно) из вашего .csproj файла из-за слияния.

Основным преимуществом использования этого пакета NPM является то, что помимо проверки для Build Action NONE он также проверяет файлы, которые НЕ включены в ваш проект. Потому что это может привести к (тонким, но противным) ошибкам при использовании Visual Studio Web Deploy. И отсутствие включений на самом деле довольно вероятно, если: 1) у вас есть 1 разработчик не VS в вашей команде, или 2) из-за слияния файла .csproj(который часто имеет проблемы слияния).

Обратитесь к странице NPM для получения инструкций. Но ниже простого примера, предполагающего, что вы используете Node и Gulp:

Простой пример

  • Установите модуль Node

    npm я check-vs-includes

  • Добавьте задачу в свой gulpfile.js:

     var checkVSIncludes = require('check-vs-includes');

     ...

     gulp.task('checkVSIncludes', function() {
        checkVSIncludes(['/Views/**/*.cshtml', '/app/**/*.js']);
     });
  1. Запустите проверку в папке проекта (например, где находится ваш файл .csproj)

    gulp checkVSIncludes

Ответ 3

Спасибо, что заработает! Мне понравилось ваше решение и проголосовали за него. У меня были небольшие проблемы с этим и в итоге было следующее:

<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>

Прямо перед тегом </Project> в файле csproj.

Ответ 4

Я предлагаю выполнить задачу пользовательской сборки. Назовите его в prebuild в вашем msbuild/tfs script. Задача пользовательской сборки должна просто проверять файл .scproj, если есть файл include cshtml с действием сборки none. Из этого просто выходим, возвращая ненулевое значение int.