[Fork] https://stackoverflow.com/questions/71570877/clone-a-jsonnode-and-attach-it-to-another-one-in-net-6

CSharp · Console

/Program.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters;
using System.IO;
using System.Data;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Reflection;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Net.Http;
using System.Text.Json.Nodes;

using System.Text.Json;
using System.Text.Json.Serialization;

using NUnit.Framework; // Throws NUnit.Framework.AssertionException

//https://stackoverflow.com/questions/71570877/clone-a-jsonnode-and-attach-it-to-another-one-in-net-6#

#nullable enable

	public static partial class JsonExtensions
	{
		public static TNode? CopyNode<TNode>(this TNode? node) where TNode : JsonNode => node?.Deserialize<TNode>();

		public static JsonNode? MoveNode(this JsonArray array, int id, JsonObject newParent, string name)
		{
			var node = array[id];
			array.RemoveAt(id); 
			return newParent[name] = node;
		}

		public static JsonNode? MoveNode(this JsonObject parent, string oldName, JsonObject newParent, string name)
		{
			parent.Remove(oldName, out var node);
			return newParent[name] = node;
		}

		public static TNode ThrowOnNull<TNode>(this TNode? value) where TNode : JsonNode => value ?? throw new JsonException("Null JSON value");
	}

	public static partial class JsonExtensions
	{
		public static string concQuest(string input, string allQuest, string questId) 
		{
			var inputObject = JsonNode.Parse(input).ThrowOnNull().AsObject();
			var allQuestArray = JsonNode.Parse(allQuest).ThrowOnNull().AsArray();
			concQuest(inputObject, allQuestArray, questId);
			return inputObject.ToJsonString();
		}		
		
		public static JsonNode? concQuest(JsonObject inputObject, JsonArray allQuestArray, string questId) 
		{
			// Enumerable.First() will throw an InvalidOperationException if no element is found satisfying the predicate.
			var node = allQuestArray.First(quest => quest!["id"]!.GetValue<string>() == questId);
			return inputObject["quest"] = node.CopyNode();
		}
	}

	public class Program
	{
		public static async Task Test()
		{
			var allQuestString = @"[{""id"":""1"", ""name"":""quest 1""},{""id"":""2"", ""name"":""quest 2""}]";
			var inputString = @"{""header"":""header value"", ""nullValue"":null}";
			var allQuestFileName = @"Question71570877-allquests.json";
			var inputFileName = @"Question71570877-quest.json";

			Console.WriteLine(inputString);
			
			await File.WriteAllTextAsync(allQuestFileName, allQuestString);
			await File.WriteAllTextAsync(inputFileName, inputString);
			
			var questId = "2"; // Or whatever
			
			JsonArray allQuest;
			using (var stream = new FileStream(allQuestFileName, new FileStreamOptions { Mode = FileMode.Open, Access = FileAccess.Read }))
				allQuest = JsonNode.Parse(stream).ThrowOnNull().AsArray();

			JsonObject input;
			using (var stream = new FileStream(inputFileName, new FileStreamOptions { Mode = FileMode.Open, Access = FileAccess.Read }))
				input = JsonNode.Parse(stream).ThrowOnNull().AsObject();

			JsonExtensions.concQuest(input, allQuest, questId);

			using (var stream = new FileStream(inputFileName, new FileStreamOptions { Mode = FileMode.Create, Access = FileAccess.Write }))
			using (var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true }))
				input.WriteTo(writer);

			Console.WriteLine(await File.ReadAllTextAsync(inputFileName));
		}

		static void TestObjectObjectMove()
		{
			var json = @"{""a"": {""b"": ""value""}}";
			
			var parent = JsonNode.Parse(json).ThrowOnNull().AsObject();

			var newParent = new JsonObject();
			
			Assert.Throws<InvalidOperationException>(() => newParent["newA"] = parent["a"]);
			var newNode = parent.MoveNode("a", newParent, "newA");
			
			Assert.AreEqual(@"{""newA"":{""b"":""value""}}", JsonSerializer.Serialize(newParent));
		}
		
		public static async Task Main(string[] args)
		{
			Console.WriteLine("Environment version: {0} ({1})", Environment.Version, System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription);
			Console.WriteLine("{0} version: {1}", typeof(JsonSerializer).Assembly.GetName().Name,  typeof(JsonSerializer).Assembly.FullName);
			Console.WriteLine();

			try
			{
				await Test();
				TestObjectObjectMove();
			}
			catch (Exception ex)
			{
				Console.WriteLine("Failed with unhandled exception: ");
				Console.WriteLine(ex);
				throw;
			}
		}
	}
;