diff --git a/src/Collections/Artemis.Plugins.PhilipsHue/Models/PhilipsHueBridge.cs b/src/Collections/Artemis.Plugins.PhilipsHue/Models/PhilipsHueBridge.cs index 77581e66..35508e73 100644 --- a/src/Collections/Artemis.Plugins.PhilipsHue/Models/PhilipsHueBridge.cs +++ b/src/Collections/Artemis.Plugins.PhilipsHue/Models/PhilipsHueBridge.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using System.Text.Json.Serialization; using Q42.HueApi; using Q42.HueApi.Interfaces; using Q42.HueApi.Models.Bridge; diff --git a/src/Collections/Artemis.Plugins.WebAPI/Controllers/DataModelController.cs b/src/Collections/Artemis.Plugins.WebAPI/Controllers/DataModelController.cs index 4c9b3483..7f1c4f02 100644 --- a/src/Collections/Artemis.Plugins.WebAPI/Controllers/DataModelController.cs +++ b/src/Collections/Artemis.Plugins.WebAPI/Controllers/DataModelController.cs @@ -1,34 +1,38 @@ using System; -using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; -using Artemis.Core.Modules; +using Artemis.Core; using Artemis.Core.Services; using Artemis.Plugins.WebAPI.Json; using EmbedIO; using EmbedIO.Routing; using EmbedIO.WebApi; -using Newtonsoft.Json; namespace Artemis.Plugins.WebAPI.Controllers { internal class DataModelController : WebApiController { private readonly IDataModelService _dataModelService; - private readonly JsonSerializerSettings _serializerSettings; + private readonly JsonSerializerOptions _serializerSettings; public DataModelController(IDataModelService dataModelService) { _dataModelService = dataModelService; - _serializerSettings = new JsonSerializerSettings {PreserveReferencesHandling = PreserveReferencesHandling.Objects, ContractResolver = new DataModelResolver()}; + _serializerSettings = new JsonSerializerOptions(CoreJson.GetJsonSerializerOptions()) + { + ReferenceHandler = ReferenceHandler.IgnoreCycles, + TypeInfoResolver = new DataModelJsonTypeInfoResolver() + }; } [Route(HttpVerbs.Get, "/data-model")] public async Task GetDataModel() { - // Use a custom ContractResolver that respects [DataModelIgnore] - string json = JsonConvert.SerializeObject(_dataModelService.GetDataModels(), _serializerSettings); + // Cast to object to avoid the generic type being serialized + string json = JsonSerializer.Serialize(_dataModelService.GetDataModels().Cast(), _serializerSettings); HttpContext.Response.ContentType = MimeType.Json; await using TextWriter writer = HttpContext.OpenResponseText(); @@ -38,12 +42,12 @@ public async Task GetDataModel() [Route(HttpVerbs.Get, "/data-model/{plugin}")] public async Task GetDataModel(Guid plugin) { - DataModel dataModel = _dataModelService.GetDataModels().FirstOrDefault(dm => dm.Module.Plugin.Guid == plugin); + // Cast to object to avoid the generic type being serialized + object dataModel = _dataModelService.GetDataModels().FirstOrDefault(dm => dm.Module.Plugin.Guid == plugin); if (dataModel == null) throw HttpException.NotFound(); - - // Use a custom ContractResolver that respects [DataModelIgnore] - string json = JsonConvert.SerializeObject(dataModel, _serializerSettings); + + string json = JsonSerializer.Serialize(dataModel, _serializerSettings); HttpContext.Response.ContentType = MimeType.Json; await using TextWriter writer = HttpContext.OpenResponseText(); diff --git a/src/Collections/Artemis.Plugins.WebAPI/Json/DataModelJsonTypeInfoResolver.cs b/src/Collections/Artemis.Plugins.WebAPI/Json/DataModelJsonTypeInfoResolver.cs new file mode 100644 index 00000000..fc45cff7 --- /dev/null +++ b/src/Collections/Artemis.Plugins.WebAPI/Json/DataModelJsonTypeInfoResolver.cs @@ -0,0 +1,36 @@ +using System; +using System.Reflection; +using System.Text.Json; +using System.Text.Json.Serialization.Metadata; +using Artemis.Core; +using Artemis.Core.Modules; + +namespace Artemis.Plugins.WebAPI.Json; + +public class DataModelJsonTypeInfoResolver : DefaultJsonTypeInfoResolver +{ + public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options) + { + JsonTypeInfo jsonTypeInfo = base.GetTypeInfo(type, options); + + if (jsonTypeInfo.Kind == JsonTypeInfoKind.Object) + { + jsonTypeInfo.Properties.Clear(); + + foreach (PropertyInfo propertyInfo in type.GetProperties(BindingFlags.Instance | BindingFlags.Public)) + { + if (propertyInfo.GetCustomAttribute() != null) + continue; + if (propertyInfo.PropertyType.IsAssignableTo(typeof(IDataModelEvent))) + continue; + + JsonPropertyInfo jsonPropertyInfo = jsonTypeInfo.CreateJsonPropertyInfo(propertyInfo.PropertyType, propertyInfo.Name); + jsonPropertyInfo.Get = propertyInfo.CanRead ? propertyInfo.GetValue : null; + jsonPropertyInfo.Set = propertyInfo.CanWrite ? (obj, value) => propertyInfo.SetValue(obj, value) : null; + jsonTypeInfo.Properties.Add(jsonPropertyInfo); + } + } + + return jsonTypeInfo; + } +} \ No newline at end of file diff --git a/src/Collections/Artemis.Plugins.WebAPI/Json/DataModelResolver.cs b/src/Collections/Artemis.Plugins.WebAPI/Json/DataModelResolver.cs deleted file mode 100644 index b26a893a..00000000 --- a/src/Collections/Artemis.Plugins.WebAPI/Json/DataModelResolver.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using Artemis.Core.Modules; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; - -namespace Artemis.Plugins.WebAPI.Json -{ - internal class DataModelResolver : DefaultContractResolver - { - #region Overrides of DefaultContractResolver - - /// - protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) - { - IList props = base.CreateProperties(type, memberSerialization); - return props.Where(p => p.PropertyType == typeof(ReadOnlyDictionary) || !p.AttributeProvider.GetAttributes(typeof(DataModelIgnoreAttribute), true).Any()).ToList(); - } - - #endregion - } -} diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 097c1f33..7c2177ef 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -18,7 +18,6 @@ - @@ -26,6 +25,7 @@ + diff --git a/src/LayerBrushes/Artemis.Plugins.LayerBrushes.RemoteControl/Models/RemoteControlBrushModel.cs b/src/LayerBrushes/Artemis.Plugins.LayerBrushes.RemoteControl/Models/RemoteControlBrushModel.cs index a4ac029f..89fe78be 100644 --- a/src/LayerBrushes/Artemis.Plugins.LayerBrushes.RemoteControl/Models/RemoteControlBrushModel.cs +++ b/src/LayerBrushes/Artemis.Plugins.LayerBrushes.RemoteControl/Models/RemoteControlBrushModel.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; +using System.Text.Json.Serialization; using Artemis.Core; -using Newtonsoft.Json; using SkiaSharp; namespace Artemis.Plugins.LayerBrushes.RemoteControl.Models @@ -24,7 +24,6 @@ public RemoteControlBrushModel(RemoteControlBrush brush, bool includeLeds) public Guid LayerId { get; set; } public string LayerName { get; set; } - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public List LedColors { get; set; } } diff --git a/src/Modules/Artemis.Plugins.Modules.TestData/TestModule.cs b/src/Modules/Artemis.Plugins.Modules.TestData/TestModule.cs index c4071ffa..f2f342e4 100644 --- a/src/Modules/Artemis.Plugins.Modules.TestData/TestModule.cs +++ b/src/Modules/Artemis.Plugins.Modules.TestData/TestModule.cs @@ -39,7 +39,6 @@ public override void Enable() }); } - public override void Disable() { } diff --git a/src/Nodes/Artemis.Plugins.Nodes.General/Converters/JsonConverter.cs b/src/Nodes/Artemis.Plugins.Nodes.General/Converters/JsonConverter.cs index acea2628..ee8f8a81 100644 --- a/src/Nodes/Artemis.Plugins.Nodes.General/Converters/JsonConverter.cs +++ b/src/Nodes/Artemis.Plugins.Nodes.General/Converters/JsonConverter.cs @@ -1,7 +1,7 @@ using System.Globalization; +using System.Text.Json; using Artemis.Core; using Avalonia.Data.Converters; -using Newtonsoft.Json; namespace Artemis.Plugins.Nodes.General.Converters; @@ -10,16 +10,24 @@ namespace Artemis.Plugins.Nodes.General.Converters; /// public class JsonConverter : IValueConverter { + private readonly JsonSerializerOptions _options; + + public JsonConverter() + { + _options = new JsonSerializerOptions(CoreJson.GetJsonSerializerOptions()); + _options.WriteIndented = true; + + } /// public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { - return JsonConvert.SerializeObject(value, Formatting.Indented); + return JsonSerializer.Serialize(value, _options); } /// public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { string? json = value?.ToString(); - return json == null ? null : JsonConvert.DeserializeObject(json, targetType); + return json == null ? null : JsonSerializer.Deserialize(json, targetType); } } \ No newline at end of file diff --git a/src/ScriptingProviders/Artemis.Plugins.ScriptingProviders.JavaScript/EmbedIO/WebSocketCommand.cs b/src/ScriptingProviders/Artemis.Plugins.ScriptingProviders.JavaScript/EmbedIO/WebSocketCommand.cs index 3ca78c13..47a406d8 100644 --- a/src/ScriptingProviders/Artemis.Plugins.ScriptingProviders.JavaScript/EmbedIO/WebSocketCommand.cs +++ b/src/ScriptingProviders/Artemis.Plugins.ScriptingProviders.JavaScript/EmbedIO/WebSocketCommand.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +using System.Text.Json; +using System.Text.Json.Serialization; namespace Artemis.Plugins.ScriptingProviders.JavaScript.EmbedIO; @@ -18,7 +19,7 @@ public WebSocketCommand(string command, string argument) public string Serialize() { - return JsonConvert.SerializeObject(this); + return JsonSerializer.Serialize(this); } public string Command { get; } diff --git a/src/ScriptingProviders/Artemis.Plugins.ScriptingProviders.JavaScript/EmbedIO/WebSocketsEditorServer.cs b/src/ScriptingProviders/Artemis.Plugins.ScriptingProviders.JavaScript/EmbedIO/WebSocketsEditorServer.cs index 1ec60d4c..419f693a 100644 --- a/src/ScriptingProviders/Artemis.Plugins.ScriptingProviders.JavaScript/EmbedIO/WebSocketsEditorServer.cs +++ b/src/ScriptingProviders/Artemis.Plugins.ScriptingProviders.JavaScript/EmbedIO/WebSocketsEditorServer.cs @@ -2,12 +2,12 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Text.Json; using System.Threading.Tasks; using Artemis.Plugins.ScriptingProviders.JavaScript.Generators; using Artemis.Plugins.ScriptingProviders.JavaScript.Scripts; using Artemis.Plugins.ScriptingProviders.JavaScript.Services; using EmbedIO.WebSockets; -using Newtonsoft.Json; namespace Artemis.Plugins.ScriptingProviders.JavaScript.EmbedIO; @@ -25,8 +25,9 @@ protected override Task OnMessageReceivedAsync(IWebSocketContext context, byte[] string content = Encoding.GetString(buffer); try { - WebSocketCommand command = JsonConvert.DeserializeObject(content); - OnWebSocketCommandReceived(new WebSocketCommandEventArgs(command)); + WebSocketCommand? command = JsonSerializer.Deserialize(content); + if (command != null) + OnWebSocketCommandReceived(new WebSocketCommandEventArgs(command)); } catch (Exception) {