Skip to content

Instantly share code, notes, and snippets.

@DamianSuess
Created September 14, 2022 20:27
Show Gist options
  • Save DamianSuess/ceb8f98339adece182372070383939b1 to your computer and use it in GitHub Desktop.
Save DamianSuess/ceb8f98339adece182372070383939b1 to your computer and use it in GitHub Desktop.
C# Json Service
// <copyright file="IJsonService.cs" company="Xeno Innovations, Inc.">
// Copyright (c) 2022 Xeno Innovations, Inc. All rights reserved.
//
// Reproduction or transmission in whole or in part, in
// any form or by any means, electronic, mechanical, or otherwise, is
// prohibited without the prior written consent of the copyright owner.
// </copyright>
// <author>Damian Suess</author>
using System.Threading.Tasks;
namespace Xeno.Common.Services
{
public interface IJsonService
{
T Deserialize<T>(string content);
Task<T> DeserializeAsync<T>(System.IO.Stream stream);
string Serialize(object o, bool indent = true);
Task SerializeAsync(System.IO.Stream stream, object o, bool indent = true);
}
}
// <copyright file="JsonExtensions.cs" company="Xeno Innovations, Inc.">
// Copyright (c) 2022 Xeno Innovations, Inc. All rights reserved.
//
// Reproduction or transmission in whole or in part, in
// any form or by any means, electronic, mechanical, or otherwise, is
// prohibited without the prior written consent of the copyright owner.
// </copyright>
// <author>Damian Suess</author>
using System;
using System.Buffers;
using System.Text.Json;
namespace Xeno.Common.Extensions
{
/// <summary>System.Text.Json extension.</summary>
public static partial class JsonExtensions
{
public static T ToObject<T>(this JsonElement element, JsonSerializerOptions options)
{
var bufferWriter = new ArrayBufferWriter<byte>();
using (var writer = new Utf8JsonWriter(bufferWriter))
{
element.WriteTo(writer);
}
return JsonSerializer.Deserialize<T>(bufferWriter.WrittenSpan, options);
}
public static T ToObject<T>(this JsonDocument document, JsonSerializerOptions options = null)
{
if (document == null)
{
throw new ArgumentNullException(nameof(document));
}
return document.RootElement.ToObject<T>(options);
}
public static object ToObject(this JsonElement element, Type returnType, JsonSerializerOptions options = null)
{
var bufferWriter = new ArrayBufferWriter<byte>();
using (var writer = new Utf8JsonWriter(bufferWriter))
{
element.WriteTo(writer);
}
return JsonSerializer.Deserialize(bufferWriter.WrittenSpan, returnType, options);
}
public static object ToObject(this JsonDocument document, Type returnType, JsonSerializerOptions options = null)
{
if (document == null)
{
throw new ArgumentNullException(nameof(document));
}
return document.RootElement.ToObject(returnType, options);
}
}
}
// <copyright file="JsonService.cs" company="Xeno Innovations, Inc.">
// Copyright (c) 2022 Xeno Innovations, Inc. All rights reserved.
//
// Reproduction or transmission in whole or in part, in
// any form or by any means, electronic, mechanical, or otherwise, is
// prohibited without the prior written consent of the copyright owner.
// </copyright>
// <author>Damian Suess</author>
using System;
using System.Text.Json;
using System.Threading.Tasks;
using XenoInc.Common.Extensions;
namespace Xeno.Common.Services
{
/// <summary>Allows devs to implement JSON without the need to hook to a specific Serializion engine and quickly upgrade in the future.</summary>
/// <remarks>
/// https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-migrate-from-newtonsoft-how-to?pivots=dotnet-5-0#dictionary-with-non-string-key
/// It would be ideal to use System.Text.Json, however, it
/// does not fully support Dictionary TKey with non-primitives types yet.
/// </remarks>
public class JsonService : IJsonService
{
public T Deserialize<T>(string json)
{
try
{
var opts = new JsonSerializerOptions();
opts.PropertyNameCaseInsensitive = true;
return System.Text.Json.JsonSerializer.Deserialize<T>(json, opts);
}
catch (Exception)
{
// _log.Error("Failed to deserialize object! " + ex.Message);
return default(T);
}
}
public async Task<T> DeserializeAsync<T>(System.IO.Stream stream)
{
try
{
var opts = new JsonSerializerOptions();
opts.PropertyNameCaseInsensitive = true;
return await JsonSerializer.DeserializeAsync<T>(stream, opts);
}
catch
{
return default(T);
}
}
public string Serialize(object obj, bool indent = true)
{
var options = new System.Text.Json.JsonSerializerOptions(JsonSerializerDefaults.Web)
{
WriteIndented = indent,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};
return System.Text.Json.JsonSerializer.Serialize(obj, options);
}
public async Task SerializeAsync(System.IO.Stream stream, object obj, bool indent = true)
{
var options = new System.Text.Json.JsonSerializerOptions(JsonSerializerDefaults.Web)
{
WriteIndented = indent,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};
await System.Text.Json.JsonSerializer.SerializeAsync(stream, obj, options);
}
/// <summary>Get object from specified JSON Element.</summary>
/// <typeparam name="T">Object type to return.</typeparam>
/// <param name="json">JSON document to parse.</param>
/// <param name="elementName">Element name.</param>
/// <returns>Element as object.</returns>
public T GetElement<T>(string json, string elementName)
{
try
{
var jDoc = System.Text.Json.JsonDocument.Parse(json);
var jsonElem = jDoc.RootElement.GetProperty(elementName);
var payload = jsonElem.ToObject<T>(new System.Text.Json.JsonSerializerOptions(JsonSerializerDefaults.Web));
return payload;
}
catch (Exception)
{
return default(T);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment