Как применить преобразование к файлу JSON во время сборки в Visual Studio?

У меня есть проект A (.NET Core), на который ссылается проект B. В проекте A у меня есть файл JSON, который необходимо обновить во время компиляции (чтобы заменить некоторые значения), и мне нужен файл JSON в построить выходные данные проекта B, которые также будут заменены.

Sln : 
    Project A
        file.json (build action : none, copy always)

    Project B
        References
            Project A

Содержимое файла A перед сборкой выглядит примерно так:

{
    key : {{this will be replaced during build}}
}

После сборки это что-то вроде:

{
    key : "VALUE"
}

До сих пор я пробовал использовать события после сборки в проекте A, и это хорошо работает для папки bin проекта A, но в папке bin проекта B у меня есть файл file.json до замены строки.

Я попытался отключить ускоренную сборку, так как думал, что это может быть проблемой, но, похоже, это не изменило результат.

Я также попробовал выполнить задачу msbuild:

  <UsingTask TaskName = "TestReplace" TaskFactory = "CodeTaskFactory" AssemblyFile = "$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
      <ParameterGroup />
      <Task>
          <Reference Include = "System.Xml" />
          <Using Namespace = "System" />
          <Using Namespace = "System.IO" />
          <Code Type = "Fragment" Language = "cs">
              <![CDATA[
var path = "file.json";
var fileContent = File.ReadAllText(path);
fileContent = fileContent.Replace("{{this will be replaced during build}}", "VALUE");
File.WriteAllText(path, fileContent);
]]>
          </Code>
      </Task>
  </UsingTask>

  <Target Name = "TestReplace" AfterTargets = "CopyFilesToOutputDirectory">
      <TestReplace />
  </Target>

Но с тем же результатом (JSON в порядке в выходной папке для проекта A, но не для проекта B)

Это задуманное поведение или я что-то неправильно настроил? И если это действительно предполагаемое поведение, какой рекомендуемый способ добиться замены строки как в проекте A, так и во всех проектах, которые от него зависят?

Я изучил генераторы одиночных файлов, но это звучит как сложное решение, и я бы предпочел избежать установки специального расширения на все компьютеры разработчиков.

Спасибо !

редактировать: кому интересно, в итоге я сделал что-то вроде этого:

<None Update = "file.json">
    <CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
    <None Update = "tmp\file.json" Link = "file.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<Target Name = "PreBuild" BeforeTargets = "PreBuildEvent">
    <Exec Command = "do something that write from file.json to tmp/file.json" />
</Target>

и я добавил tmp/ в .gitignore

Преобразуйте копию файла file.json, находящуюся в выходном каталоге, а не исходный файл в каталоге проекта. (Или, другими словами, сборка не должна вносить изменения в исходные файлы с контролем версий.)

Jonathan Dodds 27.07.2024 02:31

Это то, что я делаю сейчас, но это не работает для зависимых проектов.

vpi 27.07.2024 13:21

В приведенном вами примере кода: Задача TestReplace имеет жестко закодированный путь "file.json". Этот путь будет интерпретироваться как относительный к каталогу проекта. Задача TestReplace запускается в цели TestReplace, которая запускается после цели CopyFilesToOutputDirectory. Итак, исходный файл копируется в выходной каталог, а затем преобразуется исходный файл в каталоге проекта. Проекты, ссылающиеся на проект A, будут копироваться из выходного каталога.

Jonathan Dodds 28.07.2024 02:04

Ммм, моя вина, я слишком сильно упростил свой код перед публикацией, но путь к файлу file.json на самом деле является путем в выходной папке.

vpi 29.07.2024 12:07
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
0
4
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, что проект B на самом деле не копирует файлы из выходной папки проекта A.

Во время выполнения цели GetCopyToOutputDirectoryItems проекта B json извлекается непосредственно из A и добавляется в список _TransitiveItemsToCopyToOutputDirectory B (который позже выгружается в выходные данные B).

Вместо этого вы можете убедиться, что файл, добавленный в список <None> А, уже преобразован, а не исходный файл. Итак, подключите цель ранее к процессу сборки, выполните преобразование, а затем добавьте преобразованный файл в None.

Итак, вы предлагаете что-то вроде задачи перед сборкой, где я создаю новый файл «filereplaced.json», который, вероятно, находится в git ignore, и мне следует игнорировать file.json впоследствии во время сборки, чтобы использовать только filereplaced ? Я посмотрю и вернусь, спасибо.

vpi 26.07.2024 19:13

Что-то вроде того. Добавьте задачу раньше, затем в пределах своей цели добавьте вновь созданный файл в <None> достаточно рано, чтобы он был подхвачен остальной частью процесса сборки.

Malt 26.07.2024 19:18
<Target ...> <TestReplace /> <ItemGroup> <None ... /> </ItemGroup> </Target>
Malt 26.07.2024 19:18

Я принял ваш ответ, потому что выполнение задач по вариабилизации перед сборкой действительно работает, но я не уверен, что в конечном итоге сделаю это, хотя это кажется неправильным.

vpi 29.07.2024 12:20

Другие вопросы по теме