Created
May 28, 2021 12:48
-
-
Save mishrsud/4f9a2f18f305a6367bff2d83aac11b5a to your computer and use it in GitHub Desktop.
Snake Case Serilization with System.Text.Json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using System.Text.Json; | |
using System.Text.Json.Serialization; | |
namespace Infrastructure | |
{ | |
public static class JsonSerializationExtensions | |
{ | |
public static readonly JsonSerializerOptions SnakeCaseSerializerOptions = new() | |
{ | |
WriteIndented = false, | |
PropertyNamingPolicy = new SnakeCaseNamingPolicy(), | |
PropertyNameCaseInsensitive = true, | |
IgnoreNullValues = true, | |
Converters = { new JsonStringEnumConverter(allowIntegerValues: false) } | |
}; | |
/// <summary> | |
/// Converts the object instance passed in to JSON using <see cref="System.Text.Json.JsonSerializer"/> | |
/// </summary> | |
/// <param name="objectToSerialize">The object instance to serialize</param> | |
/// <param name="serializerOptions">A <see cref="JsonSerializerOptions"/> instance. Defaults to snake_case</param> | |
/// <typeparam name="T"></typeparam> | |
public static string ToJson<T>(this T objectToSerialize, JsonSerializerOptions? serializerOptions = null) | |
{ | |
return JsonSerializer.Serialize(objectToSerialize, serializerOptions ?? SnakeCaseSerializerOptions); | |
} | |
/// <summary> | |
/// Converts the string passed in to an instance of T using <see cref="System.Text.Json.JsonSerializer"/> | |
/// </summary> | |
/// <param name="json">The string to convert</param> | |
/// <param name="serializerOptions">A <see cref="JsonSerializerOptions"/> instance. Defaults to snake_case</param> | |
/// <typeparam name="T"></typeparam> | |
public static T FromJson<T>(this string json, JsonSerializerOptions? serializerOptions = null) | |
{ | |
return JsonSerializer.Deserialize<T>(json, serializerOptions ?? SnakeCaseSerializerOptions)!; | |
} | |
// Copied from https://github.com/michaelrosedev/snakecase_json/blob/dbc70b7e137e42716350685f684bd46d0458d056/Sample.Serialization/StringExtensions.cs#L12 | |
public static string ToSnakeCaseAsSpan(this string str) | |
{ | |
const char Separator = '_'; | |
if (str == null) | |
{ | |
return string.Empty; | |
} | |
var strSpan = str.AsSpan(); | |
var bufferSize = str.Length + str.Count(t => t >= 'A' && t <= 'Z' && t != str[0]); | |
Span<char> buffer = new char[bufferSize]; | |
var bufferPosition = 0; | |
var namePosition = 0; | |
while (bufferPosition < buffer.Length) | |
{ | |
if (namePosition > 0 && strSpan[namePosition] >= 'A' && strSpan[namePosition] <= 'Z') | |
{ | |
buffer[bufferPosition] = Separator; | |
buffer[bufferPosition + 1] = strSpan[namePosition]; | |
bufferPosition += 2; | |
namePosition++; | |
continue; | |
} | |
buffer[bufferPosition] = strSpan[namePosition]; | |
bufferPosition++; | |
namePosition++; | |
} | |
return new string(buffer).ToLower(); | |
} | |
} | |
public class SnakeCaseNamingPolicy : JsonNamingPolicy | |
{ | |
public override string ConvertName(string name) | |
{ | |
return name.ToSnakeCaseAsSpan(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment