Skip to content

Instantly share code, notes, and snippets.

@Aetopia
Created August 25, 2024 12:04
Show Gist options
  • Save Aetopia/68bddfbc453f329c1c67fa6c8c15ed14 to your computer and use it in GitHub Desktop.
Save Aetopia/68bddfbc453f329c1c67fa6c8c15ed14 to your computer and use it in GitHub Desktop.
A simple wrapper class that wraps all .NET Framework JSON serializers.
#pragma warning disable IDE0130
namespace System.Runtime.Serialization.Json;
#pragma warning restore IDE0130
using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;
using System.Collections.Generic;
using System.Web.Script.Serialization;
public static class Json
{
static readonly Dictionary<Type, DataContractJsonSerializer> serializers = [];
static readonly DataContractJsonSerializerSettings settings = new() { UseSimpleDictionaryFormat = true };
static readonly JavaScriptSerializer serializer = new() { MaxJsonLength = int.MaxValue, RecursionLimit = int.MaxValue };
static DataContractJsonSerializer _(Type type) { if (!serializers.TryGetValue(type, out var value)) serializers.Add(type, value = new(type, settings)); return value; }
static bool Contains<T>(this Type type) => type == typeof(T) || type.GenericTypeArguments.Any(_ => _ == typeof(T) || _.Contains<T>());
/// <summary>
/// Converts an object to a JSON string.
/// </summary>
/// <param name="value">The object to serialize.</param>
/// <returns>The serialized JSON string.</returns>
public static string Serialize(object value)
{
var type = value.GetType();
if (type.Contains<object>()) return serializer.Serialize(value);
using MemoryStream stream = new();
_(type).WriteObject(stream, value);
return Encoding.UTF8.GetString(stream.ToArray());
}
/// <summary>
/// Converts a JSON-formatted string to an object of the specified type.
/// </summary>
/// <typeparam name="T">The type of the resulting object.</typeparam>
/// <param name="value">The JSON string to deserialize.</param>
/// <returns>The deserialized object.</returns>
public static T Deserialize<T>(string value)
{
var type = typeof(T);
if (type.Contains<object>()) return serializer.Deserialize<T>(value);
var buffer = Encoding.Unicode.GetBytes(value);
object obj = null;
if (type == typeof(XElement) || type == typeof(XmlDocument) || type == typeof(XPathNavigator))
{
using var reader = JsonReaderWriterFactory.CreateJsonReader(buffer, XmlDictionaryReaderQuotas.Max);
if (type == typeof(XElement)) obj = XElement.Load(reader);
else if (type == typeof(XmlDocument)) { XmlDocument document = new(); document.Load(reader); @obj = document; }
else if (type == typeof(XElement)) @obj = new XPathDocument(reader).CreateNavigator();
}
else using (MemoryStream stream = new(buffer)) @obj = _(type).ReadObject(stream);
return (T)obj;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment