[Fork] questions/51802068/how-to-escape-especial-characters-in-json

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 Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;	

//https://stackoverflow.com/questions/51802068/how-to-escape-especial-characters-in-json?noredirect=1#comment90566353_51802068
    //https://stackoverflow.com/questions/51845381/how-to-escape-embedded-json-after-unescape
    public class VData
    {
        public object RNumber { get; set; }
        public string BRNumber { get; set; }
    }

    public class Number
    {
        [JsonProperty("@paraID")]
        public string paraID { get; set; }
        [JsonProperty("@Value")]
        public string Value { get; set; }
        [JsonProperty("@label")]
        public string label { get; set; }
    }

    public class Evaluation
    {
        public List<Number> number { get; set; }
    }

    public class JsonFile
    {
        public Evaluation evaluation { get; set; }
		public DateTime DateTime = DateTime.UtcNow;
		public string PossibleNull = null;
    }

    public class OnlineFields
    {
        public string CCode { get; set; }
        public string MNumber { get; set; }
        public string Product { get; set; }
		
		[JsonConverter(typeof(EmbeddedLiteralConverter<JsonFile>))]
        public JsonFile JsonFile { get; set; }
    }

    public class Response
    {
        public object Message { get; set; }
        public bool Error { get; set; }
        public VData VData { get; set; }
        public OnlineFields onlineFields { get; set; }
		
		public DateTime DateTime = DateTime.UtcNow;
		public string PossibleNull = null;
    }

    public class EmbeddedLiteralConverter<T> : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return typeof(T).IsAssignableFrom(objectType);
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            using (new PushValue<bool>(true, () => Disabled, (canWrite) => Disabled = canWrite))
            {
                using (var sw = new StringWriter(writer.Culture))
                {
                    // Copy relevant settings
                    using (var nestedWriter = new JsonTextWriter(sw) 
                    { 
                        DateFormatHandling = writer.DateFormatHandling,
                        DateFormatString = writer.DateFormatString,
                        DateTimeZoneHandling = writer.DateTimeZoneHandling,
                        StringEscapeHandling = writer.StringEscapeHandling,
                        FloatFormatHandling = writer.FloatFormatHandling,
                        Culture = writer.Culture,
						// Remove if you don't want the escaped \r\n characters in the embedded JSON literal:
                        Formatting = writer.Formatting, 
                    })
                    {
                        serializer.Serialize(nestedWriter, value);
                    }
                    writer.WriteValue(sw.ToString());
                }
            }
        }

        [ThreadStatic]
        static bool disabled;

        // Disables the converter in a thread-safe manner.
        bool Disabled { get { return disabled; } set { disabled = value; } }

        public override bool CanWrite { get { return !Disabled; } }

        public override bool CanRead { get { return !Disabled; } }
		
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
                return null;
            var contract = serializer.ContractResolver.ResolveContract(objectType);
            if (contract is JsonPrimitiveContract)
                throw new JsonSerializationException("Invalid type: " + objectType);
            if (existingValue == null)
                existingValue = contract.DefaultCreator();
            if (reader.TokenType == JsonToken.String)
            {
                var json = (string)JToken.Load(reader);
                using (var subReader = new JsonTextReader(new StringReader(json)))
                {
                    // By populating a pre-allocated instance we avoid an infinite recursion in EmbeddedLiteralConverter<T>.ReadJson()
                    // Re-use the existing serializer to preserve settings.
                    serializer.Populate(subReader, existingValue);
                }
            }
            else
            {
                serializer.Populate(reader, existingValue);
            }
            return existingValue;
        }
    }

    struct PushValue<T> : IDisposable
    {
        Action<T> setValue;
        T oldValue;

        public PushValue(T value, Func<T> getValue, Action<T> setValue)
        {
            if (getValue == null || setValue == null)
                throw new ArgumentNullException();
            this.setValue = setValue;
            this.oldValue = getValue();
            setValue(value);
        }

        #region IDisposable Members

        // By using a disposable struct we avoid the overhead of allocating and freeing an instance of a finalizable class.
        public void Dispose()
        {
            if (setValue != null)
                setValue(oldValue);
        }

        #endregion
    }

    class TestClass
    {
        public static void Test()
        {
            var testJson = GetJson();
			
			var settings = new JsonSerializerSettings
			{
				Converters = { new EmbeddedLiteralConverter<JsonFile>() },
				DateFormatString = "yyyy-MM-dd",
				NullValueHandling = NullValueHandling.Ignore,
			};

            var response = JsonConvert.DeserializeObject<Response>(testJson, settings);

            var json2 = JsonConvert.SerializeObject(response, Formatting.Indented, settings);

            Console.WriteLine(json2);
        }

        static string GetJson()
        {
            var json = @"{  
   ""Message"":null,
   ""Error"":false,
   ""VData"":{  
      ""RNumber"":null,
      ""BRNumber"":""Session1""
   },
   ""onlineFields"":{  
      ""CCode"":""Web"",
      ""MNumber"":""15478655"",
      ""Product"":""100"",
      ""JsonFile"":""      {  
         \""evaluation\"":{  
            \""number\"":[  
               {  
                  \""@paraID\"":\""1000\"",
                  \""@Value\"":\""\"",
                  \""@label\"":\""We are america\""
               },
               {  
                  \""@paraID\"":\""2000\"",
                  \""@Value\"":\""100\"",
                  \""@label\"":\""We are japan\""
               },
               {  
                  \""@paraID\"":\""3000\"",
                  \""@Value\"":\""1000\"",
                  \""@label\"":\""We are UK\""
               },
               {  
                  \""@paraID\"":\""4000\"",
                  \""@Value\"":\""\"",
                  \""@label\"":\""We are China\""
               }
            ]
         }
      } ""     
   }
}";
            return json;
        }
    }

	public class Program
	{
		public static void Main()
		{
			Console.WriteLine("Environment version: " + Environment.Version);
			Console.WriteLine("Json.NET version: " + typeof(JsonSerializer).Assembly.FullName);
			Console.WriteLine();

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

    public class AssertionFailedException : System.Exception
    {
        public AssertionFailedException() : base() { }

        public AssertionFailedException(string s) : base(s) { }
    }

    public static class Assert
    {
        public static void IsTrue(bool value)
        {
            IsTrue(value, "failed");
        }

        public static void IsTrue(bool value, string message)
        {
            if (value == false)
                throw new AssertionFailedException(message ?? "failed");
        }
    }
;