[Fork] [Fork] https://stackoverflow.com/questions/67529579/crash-after-serializing-jobject-with-datacontractserializer-and-xmldictionarywri

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.Xml.Schema;
using System.Xml;
using System.Xml.Serialization;

using System.Runtime.Serialization;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;


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

	//https://stackoverflow.com/questions/67529579/crash-after-serializing-jobject-with-datacontractserializer-and-xmldictionarywri

    public class RecursiveList<T> : List<RecursiveList<T>>
    {
    }

    public class RecursiveListStringSurrogate
    {
		// A dummy surrogate that serializes nothing, for testing purposes.
    }

    public class RecursiveListStringSurrogateSelector : ISerializationSurrogateProvider
    {
        public object GetDeserializedObject(object obj, Type targetType)
        {
            if (obj is RecursiveListStringSurrogate)
                return new RecursiveList<string>();
            return obj;
        }

        public object GetObjectToSerialize(object obj, Type targetType)
        {
            if (obj is RecursiveList<string>)
                return new RecursiveListStringSurrogate();
            return obj;
        }

		public Type GetSurrogateType(Type type) 
		{
            if (type == typeof(RecursiveList<string>))
                return typeof(RecursiveListStringSurrogate);
			return type;
		}
    }

	public class Model
	{
		public RecursiveList<string> List { get; set; }
	}

    public static partial class DataContractSerializerHelper
    {
        public static string ToContractXml<T>(this T obj, DataContractSerializer serializer = null, XmlWriterSettings settings = null)
        {
            serializer = serializer ?? new DataContractSerializer(obj == null ? typeof(T) : obj.GetType());
            using (var textWriter = new StringWriter())
            {
                settings = settings ?? new XmlWriterSettings { Indent = true };
                using (var xmlWriter = XmlWriter.Create(textWriter, settings))
                {
                    serializer.WriteObject(xmlWriter, obj);
                }
                return textWriter.ToString();
            }
        }

        public static T FromContractXml<T>(this string xml, DataContractSerializer serializer = null)
        {
            using (var textReader = new StringReader(xml ?? ""))
            using (var xmlReader = XmlReader.Create(textReader))
            {
                return (T)(serializer ?? new DataContractSerializer(typeof(T))).ReadObject(xmlReader);
            }
        }
    }

    class TestClass
    {
        public static void Test()
        {
			Test(new List<string> ());
			Test(new List<List<string>> ());
			Test(new List<List<List<string>>> ());
			
			Test(new RecursiveList<string>());
			
			//Test(new Model { List = new RecursiveList<string>() });
		}

		static void Test<T>(T root)
		{
            var surrogate = new RecursiveListStringSurrogateSelector();

			var serializer = new DataContractSerializer(root.GetType());
			serializer.SetSerializationSurrogateProvider(surrogate);

            MemoryStream stream1 = new MemoryStream();
            var writer = XmlDictionaryWriter.CreateBinaryWriter(stream1);
            serializer.WriteObject(writer, root);
            writer.Flush();
            Console.WriteLine(System.Text.Encoding.UTF8.GetString(stream1.GetBuffer(), 0, checked((int)stream1.Length)));

			var xml = root.ToContractXml(serializer);
			Console.WriteLine(xml);
			Console.WriteLine();
		}
	}

	public class Program
	{
		public static void Main()
		{
			Console.WriteLine("Environment version: {0} ({1})", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , GetNetCoreVersion());
			Console.WriteLine();

			try
			{
				TestClass.Test();
			}
			catch (Exception ex)
			{
				Console.WriteLine("Failed with unhandled exception: ");
				Console.WriteLine(ex);
				throw;
			}
		}
		
		public static string GetNetCoreVersion()
		{
			//https://techblog.dorogin.com/how-to-detect-net-core-version-in-runtime-ecd65ad695be
			//
			var assembly = typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly;
			var assemblyPath = assembly.Location.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
			int netCoreAppIndex = Array.IndexOf(assemblyPath, "Microsoft.NETCore.App");
			if (netCoreAppIndex > 0 && netCoreAppIndex < assemblyPath.Length - 2)
				return assemblyPath[netCoreAppIndex + 1];
			return null;
		}
	}
;