< Summary - Core.Tests

Information
Class: Common.Core.Classes.JsonHelper
Assembly: Common.Core
File(s): D:\a\NuGetPackages\NuGetPackages\src\Common\Core\Classes\JsonHelper.cs
Tag: 3_8508158812
Line coverage
100%
Covered lines: 90
Uncovered lines: 0
Coverable lines: 90
Total lines: 190
Line coverage: 100%
Branch coverage
100%
Covered branches: 36
Total branches: 36
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
DeserializeFile(...)100%44100%
DeserializeJson(...)100%22100%
DeserializeList(...)100%66100%
ReadJsonFromFile(...)100%44100%
ReadAppSettings(...)100%1010100%
Serialize(...)100%66100%
Serialize(...)100%44100%
DefaultSerializerOptions()100%11100%

File(s)

D:\a\NuGetPackages\NuGetPackages\src\Common\Core\Classes\JsonHelper.cs

#LineLine coverage
 1using System.Security;
 2using System.Text.Encodings.Web;
 3using System.Text.Json;
 4using System.Text.Unicode;
 5
 6namespace Common.Core.Classes;
 7
 8/// <summary>Class to provide Json file loading and saving.</summary>
 9public static class JsonHelper
 10{
 11  /// <summary>Reads a Json file and populates an object.</summary>
 12  /// <typeparam name="T">Generic class or interface.</typeparam>
 13  /// <param name="fileName">Json file name.</param>
 14  /// <param name="options">Optional Json serializer options.</param>
 15  /// <returns><see langword="null"/> is returned if the object could not be populated.</returns>
 16  /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid.</exception
 17  /// <exception cref="IOException">Thrown when an I/O error occurs.</exception>
 18  /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported, or when there
 19  /// is an attempt to read, seek, or write to a stream that does not support the invoked functionality.</exception>
 20  /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue.</exception>
 21  /// <exception cref="SecurityException">Thrown when a security error is detected.</exception>
 22  /// <exception cref="UnauthorizedAccessException">Thrown when the operating system denies access because of an I/O err
 23  public static T? DeserializeFile<T>( string fileName, JsonSerializerOptions? options = null ) where T : class
 224  {
 225    T? rtn = null;
 226    string? json = ReadJsonFromFile( fileName );
 227    options ??= DefaultSerializerOptions();
 228    return json is null ? rtn : DeserializeJson<T>( ref json, options );
 229  }
 30
 31  /// <summary>Reads a Json string and populates an object.</summary>
 32  /// <typeparam name="T">Generic class or interface.</typeparam>
 33  /// <param name="json">Json string.</param>
 34  /// <param name="options">Optional Json serializer options.</param>
 35  /// <returns><see langword="null"/> is returned if the object could not be populated.</returns>
 36  public static T? DeserializeJson<T>( ref string json, JsonSerializerOptions? options = null ) where T : class
 4237  {
 4238    T? rtn = null;
 39    try
 4240    {
 4241      options ??= DefaultSerializerOptions();
 4242      rtn = JsonSerializer.Deserialize<T>( json, options );
 4143    }
 344    catch( Exception ) { }
 45
 4246    return rtn;
 4247  }
 48
 49  /// <summary>Populates a list of objects from a Json string.</summary>
 50  /// <typeparam name="T">Generic class or interface.</typeparam>
 51  /// <param name="json">Json string.</param>
 52  /// <param name="options">Optional Json serializer options</param>
 53  /// <returns>An empty list is returned if the string could not be converted.</returns>
 54  public static List<T> DeserializeList<T>( ref string? json, JsonSerializerOptions? options = null )
 255  {
 256    List<T> rtn = [];
 257    if( json is not null )
 258    {
 259      options ??= DefaultSerializerOptions();
 60      try
 261      {
 262        List<T>? obj = JsonSerializer.Deserialize<List<T>>( json, options );
 463        if( obj is not null ) { rtn = obj; }
 164      }
 365      catch( Exception ) { }
 266    }
 67
 268    return rtn;
 269  }
 70
 71  /// <summary>Reads the Json from a file.</summary>
 72  /// <param name="fileName">Json file name.</param>
 73  /// <returns><see langword="null"/> is returned if the file could not be accessed.</returns>
 74  /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid.</exception
 75  /// <exception cref="IOException">Thrown when an I/O error occurs.</exception>
 76  /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported, or when there
 77  /// is an attempt to read, seek, or write to a stream that does not support the invoked functionality.</exception>
 78  /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue.</exception>
 79  /// <exception cref="SecurityException">Thrown when a security error is detected.</exception>
 80  /// <exception cref="UnauthorizedAccessException">Thrown when the operating system denies access because of an I/O err
 81  public static string? ReadJsonFromFile( string fileName )
 882  {
 1283    if( string.IsNullOrWhiteSpace( fileName ) ) { return null; }
 684    string? json = null;
 685    FileInfo fi = new( fileName );
 686    if( fi.Exists )
 587    {
 588      using StreamReader sr = new( fi.FullName );
 589      json = sr.ReadToEnd();
 590    }
 91
 692    return json;
 893  }
 94
 95  /// <summary>Returns a collection of settings from a Json application settings file.</summary>
 96  /// <param name="fileName">Json application settings file name.</param>
 97  /// <param name="section">Application settings section to return <i>(case-sensitive)</i>.</param>
 98  /// <param name="maxDepth">Maximum depth allowed when parsing JSON data.</param>
 99  /// <returns>An empty collection is returned if the settings section could not be found.</returns>
 100  /// <remarks>If no section is provided it is assumed that the settings are in the root.
 101  /// <br/>Otherwise it is assumed that the section name is case-sensitive and only 3 levels deep.</remarks>
 102  public static Dictionary<string, string?> ReadAppSettings( ref string fileName, ref string? section, int maxDepth = 2 
 4103  {
 4104    Dictionary<string, string?> rtn = [];
 105    try
 4106    {
 4107      if( string.IsNullOrEmpty( Path.GetDirectoryName( fileName ) ) )
 1108      {
 1109        fileName = ReflectionHelper.AddCurrentPath( fileName );
 1110      }
 4111      string? json = ReadJsonFromFile( fileName );
 6112      if( string.IsNullOrWhiteSpace( json ) ) { return rtn; }
 3113      JsonDocumentOptions options = new()
 3114      {
 3115        AllowTrailingCommas = true,
 3116        MaxDepth = maxDepth,
 3117        CommentHandling = JsonCommentHandling.Skip
 3118      };
 3119      using JsonDocument document = JsonDocument.Parse( json, options );
 2120      JsonElement coll = document.RootElement;
 4121      if( !string.IsNullOrEmpty( section ) ) { coll = coll.GetProperty( section ); }
 33122      foreach( JsonProperty prop in coll.EnumerateObject() )
 15123      {
 15124        if( prop.Value.ValueKind is not JsonValueKind.Object )
 15125        {
 15126          rtn.Add( prop.Name, prop.Value.ToString() );
 15127        }
 15128      }
 1129    }
 6130    catch( Exception ) { }
 131
 3132    return rtn;
 4133  }
 134
 135  /// <summary>Writes a Json file of the provided object type.</summary>
 136  /// <typeparam name="T">Generic class or interface.</typeparam>
 137  /// <param name="obj">Object to save.</param>
 138  /// <param name="fileName">Json file name.</param>
 139  /// <param name="options">Optional Json serializer options.</param>
 140  /// <returns><see langword="true"/> if the object was saved.</returns>
 141  /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid.</exception
 142  /// <exception cref="IOException">Thrown when an I/O error occurs.</exception>
 143  /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported, or when there
 144  /// is an attempt to read, seek, or write to a stream that does not support the invoked functionality.</exception>
 145  /// <exception cref="SecurityException">Thrown when a security error is detected.</exception>
 146  /// <exception cref="UnauthorizedAccessException">Thrown when the operating system denies access because of an I/O err
 147  public static bool Serialize<T>( T? obj, string fileName, JsonSerializerOptions? options = null ) where T : class
 3148  {
 5149    if( obj is null || string.IsNullOrWhiteSpace( fileName ) ) { return false; }
 2150    options ??= DefaultSerializerOptions();
 2151    string json = JsonSerializer.Serialize( obj, options );
 2152    File.WriteAllText( fileName, json );
 2153    return true;
 3154  }
 155
 156  /// <summary>Returns a Json string of the provided object type.</summary>
 157  /// <typeparam name="T">Generic class or interface.</typeparam>
 158  /// <param name="obj">Object to serialize.</param>
 159  /// <param name="options">Optional Json serializer options.</param>
 160  /// <returns><see langword="null"/> is returned if the serialization fails.</returns>
 161  /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported, or when there
 162  /// is an attempt to read, seek, or write to a stream that does not support the invoked functionality.</exception>
 163  public static string? Serialize<T>( T? obj, JsonSerializerOptions? options = null ) where T : class
 10164  {
 16165    if( obj is null ) { return null; }
 7166    options ??= DefaultSerializerOptions();
 7167    return JsonSerializer.Serialize( obj, options );
 10168  }
 169
 170  /// <summary>Gets a default set of Json Serializer options.</summary>
 171  /// <returns>
 172  /// <code>
 173  /// AllowTrailingCommas = true
 174  /// IgnoreReadOnlyProperties = true
 175  /// MaxDepth = 6
 176  /// PropertyNameCaseInsensitive = true
 177  /// </code>
 178  /// </returns>
 179  public static JsonSerializerOptions DefaultSerializerOptions()
 69180  {
 69181    return new JsonSerializerOptions
 69182    {
 69183      AllowTrailingCommas = true,
 69184      IgnoreReadOnlyProperties = true,
 69185      MaxDepth = 6,
 69186      PropertyNameCaseInsensitive = true,
 69187      Encoder = JavaScriptEncoder.Create( UnicodeRanges.BasicLatin ),
 69188    };
 69189  }
 190}