Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ public partial class BaseViewModel : ViewModelBase
```

#### JsonConvertHelper
This `Class` uses Newtonsoft.JSON in order to serialize and deserialize objects to strings and vice reverse.
This `Class` uses System.Text.Json in order to serialize and deserialize objects to strings and vice reverse.
This is helpful if you want to store Collections or custom objects in the MAUI.Preferences (Settings).

```cs
Expand Down
3 changes: 2 additions & 1 deletion conditions.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
<Project>
<PropertyGroup>
<!-- Here you can choose if you want to build as executable or as package -->
<!-- Enable additionally Newtonsoft.JSON -->
<!--<DefineConstants>$(DefineConstants);NEWTONSOFT</DefineConstants>-->
<!--<DefineConstants>$(DefineConstants);NET9</DefineConstants>-->
<!----><DefineConstants>$(DefineConstants);NET10</DefineConstants>
<DefineConstants>$(DefineConstants);NET10</DefineConstants>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ namespace AndreasReitberger.Shared.Core.Licensing.SourceGeneration
[JsonSourceGenerationOptions(WriteIndented = true)]
public partial class LicenseSourceGenerationContext : JsonSerializerContext { }

}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Firebase.Auth;
using Newtonsoft.Json;
using AndreasReitberger.Shared.Firebase.SourceGeneration;
using Firebase.Auth;
using System.Text.Json;

namespace AndreasReitberger.Shared.Firebase.Events
{
Expand All @@ -12,7 +13,8 @@ public partial class CurrentUserChangedEventArgs : EventArgs
#endregion

#region Overrides
public override string ToString() => JsonConvert.SerializeObject(this, Formatting.Indented);

public override string ToString() => JsonSerializer.Serialize(this!, FirebaseSourceGenerationContext.Default.CurrentUserChangedEventArgs);

#endregion
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Firebase.Auth;
using Newtonsoft.Json;
using AndreasReitberger.Shared.Firebase.SourceGeneration;
using Firebase.Auth;
using System.Text.Json;

namespace AndreasReitberger.Shared.Firebase.Events
{
Expand All @@ -13,7 +14,7 @@ public partial class UserDataChangedEventArgs : EventArgs
#endregion

#region Overrides
public override string ToString() => JsonConvert.SerializeObject(this, Formatting.Indented);
public override string ToString() => JsonSerializer.Serialize(this!, FirebaseSourceGenerationContext.Default.UserDataChangedEventArgs);

#endregion
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using AndreasReitberger.Shared.Core.Localization;
using AndreasReitberger.Shared.Firebase.Events;
using System.Text.Json.Serialization;

namespace AndreasReitberger.Shared.Firebase.SourceGeneration
{
[JsonSerializable(typeof(CurrentUserChangedEventArgs))]
[JsonSerializable(typeof(UserDataChangedEventArgs))]
[JsonSourceGenerationOptions(WriteIndented = true)]
public partial class FirebaseSourceGenerationContext : JsonSerializerContext { }
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ public class LanguageChangedEventArgs : EventArgs
#endregion

#region Overrides

public override string ToString() => JsonSerializer.Serialize(this!, CoreSourceGenerationContext.Default.LanguageChangedEventArgs);

#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ public LocalizationInfo(string name, string nativeName, Uri flagUri, string tran
#endregion

#region Overrides

public override string ToString() => JsonSerializer.Serialize(this!, CoreSourceGenerationContext.Default.LocalizationInfo);

#endregion
}
}
14 changes: 3 additions & 11 deletions src/SharedNetCoreLibrary/SharedNetCoreLibrary.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,17 @@
</PropertyGroup>
<ItemGroup>
<None Include="..\..\licenses\CommunityToolkit.Mvvm.txt" Link="Licenses\CommunityToolkit.Mvvm.txt" />
<None Include="..\..\licenses\Newtonsoft.Json.txt" Link="Licenses\Newtonsoft.Json.txt" />
<None Condition="'$(DefineConstants.Contains(NEWTONSOFT))'" Include="..\..\licenses\Newtonsoft.Json.txt" Link="Licenses\Newtonsoft.Json.txt" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="System.Text.Json" Version="10.0.1" />
<None Include="..\..\README.md" Pack="true" PackagePath="\" />
</ItemGroup>
<!--
<ItemGroup Condition="'$(DefineConstants.Contains(NEWTONSOFT))'">
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
</ItemGroup>
<ItemGroup Condition="'!$(DefineConstants.Contains(NEWTONSOFT))'">
<PackageReference Include="System.Text.Json" Version="10.0.0" />
</ItemGroup>
-->
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="System.Text.Json" Version="10.0.1" />
</ItemGroup>

<ItemGroup>
<Folder Include="Licenses\" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ namespace AndreasReitberger.Shared.Core.SourceGeneration
[JsonSourceGenerationOptions(WriteIndented = true)]
public partial class CoreSourceGenerationContext : JsonSerializerContext { }

}
}
83 changes: 62 additions & 21 deletions src/SharedNetCoreLibrary/Utilities/JsonConvertHelper.cs
Original file line number Diff line number Diff line change
@@ -1,57 +1,101 @@
#if NEWTONSOFT
using Newtonsoft.Json;
using JsonSerializer = System.Text.Json.JsonSerializer;
#endif

namespace AndreasReitberger.Shared.Core.Utilities
{
public partial class JsonConvertHelper
{
#region Converts
#if NEWTONSOFT
public static T? ToObject<T>(string jsonString, T? defaultValue = default, Action<Exception>? OnError = null, JsonSerializerSettings? settings = null)
#else
/// <summary>
/// Deserializes the specified JSON string to an object of type T using System.Text.JSON.
/// Returns a default value if deserialization fails.
/// </summary>
/// <remarks>If the input JSON string is not a valid JSON representation of type T, or if an
/// exception occurs during deserialization, the method returns the specified default value and optionally
/// invokes the OnError callback. When T is string and the input is not a quoted JSON string, the method returns
/// the raw string value.</remarks>
/// <typeparam name="T">The type of the object to deserialize to.</typeparam>
/// <param name="jsonString">The JSON string to deserialize. If T is string and the input is not a quoted JSON string, the raw value is
/// returned as a string.</param>
/// <param name="defaultValue">The value to return if deserialization fails or the result is null. The default is the default value of type
/// T.</param>
/// <param name="OnError">An optional callback that is invoked with the exception if an error occurs during deserialization.</param>
/// <param name="settings">An optional JsonSerializerContext to use for deserialization. If null, a default context is used.</param>
/// <returns>An object of type T deserialized from the JSON string, or the specified default value if deserialization
/// fails.</returns>
public static T? ToObject<T>(string jsonString, T? defaultValue = default, Action<Exception>? OnError = null, JsonSerializerContext? settings = null)
#endif
{
try
{
settings ??= CoreSourceGenerationContext.Default;
// Check if it is saved as plain string. If so, just return the string
if (typeof(T) == typeof(string) && !(jsonString.StartsWith('"') && jsonString.EndsWith('"')))
return (T)Convert.ChangeType(jsonString, typeof(T));
else
return (T?)JsonSerializer.Deserialize(jsonString, typeof(T), settings) ?? defaultValue;
}
catch (Exception exc)
{
OnError?.Invoke(exc);
return defaultValue;
}
}

#if NEWTONSOFT
public static T? ToObjectN<T>(string jsonString, T? defaultValue = default, Action<Exception>? OnError = null, JsonSerializerSettings? settings = null)
{
try
{
settings ??= new JsonSerializerSettings()
{
Error = (a, b) =>
{
throw new JsonReaderException($"Exception while deserializing the object type `{typeof(T)}` from the string `{jsonString}");
}
};
#else
settings ??= CoreSourceGenerationContext.Default;
#endif
// Check if it is saved as plain string. If so, just return the string
if (typeof(T) == typeof(string) && !(jsonString.StartsWith('"') && jsonString.EndsWith('"')))
return (T)Convert.ChangeType(jsonString, typeof(T));
else
#if NEWTONSOFT
return JsonConvert.DeserializeObject<T>(jsonString, settings) ?? defaultValue;
#else
//return JsonSerializer.Deserialize<T>(jsonString, settings) ?? defaultValue;
return (T?)JsonSerializer.Deserialize(jsonString, typeof(T), settings) ?? defaultValue;
#endif
}
catch (Exception exc)
{
OnError?.Invoke(exc);
return defaultValue;
}
}
#if NEWTONSOFT
public static string? ToSettingsString<T>(T settingsObject, string? defaultValue = default, Action<Exception>? OnError = null, JsonSerializerSettings? settings = null)
#else
public static string? ToSettingsString<T>(T settingsObject, string? defaultValue = default, Action<Exception>? OnError = null, JsonSerializerContext? settings = null)
#endif

/// <summary>
/// Serializes the specified settings object to a JSON string representation using System.Text.JSON.
/// </summary>
/// <typeparam name="T">The type of the object to serialize.</typeparam>
/// <param name="settingsObject">The object to serialize to a JSON string. Can be null.</param>
/// <param name="defaultValue">The value to return if serialization fails or results in null. The default is null.</param>
/// <param name="OnError">An optional callback that is invoked if an exception occurs during serialization. Can be null.</param>
/// <param name="settings">The optional source generation context to use for serialization. If null, the default context is used.</param>
/// <returns>A JSON string representation of the settings object, or the specified default value if serialization fails.</returns>
public static string? ToSettingsString<T>(T settingsObject, string? defaultValue = default, Action<Exception>? OnError = null, JsonSerializerContext? settings = null)
{
try
{
settings ??= CoreSourceGenerationContext.Default;
return JsonSerializer.Serialize(settingsObject, typeof(T), settings) ?? defaultValue;
}
catch (Exception exc)
{
OnError?.Invoke(exc);
return defaultValue;
}
}

#if NEWTONSOFT
public static string? ToSettingsStringN<T>(T settingsObject, string? defaultValue = default, Action<Exception>? OnError = null, JsonSerializerSettings? settings = null)
{
try
{
settings ??= new JsonSerializerSettings()
{
Error = (a, b) =>
Expand All @@ -60,17 +104,14 @@ public partial class JsonConvertHelper
}
};
return JsonConvert.SerializeObject(settingsObject, Formatting.Indented, settings) ?? defaultValue;
#else
settings ??= CoreSourceGenerationContext.Default;
return JsonSerializer.Serialize(settingsObject, typeof(T), settings) ?? defaultValue;
#endif
}
catch (Exception exc)
{
OnError?.Invoke(exc);
return defaultValue;
}
}
#endif
#endregion
}
}
3 changes: 2 additions & 1 deletion src/SharedNetCoreLibrary/Utilities/JsonPrivateResolver.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#if NEWTONSOFT
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Reflection;
using JsonProperty = Newtonsoft.Json.Serialization.JsonProperty;

namespace AndreasReitberger.Shared.Core.Utilities
{
Expand Down
Loading
Loading