Skip to content

Commit

Permalink
Standardize .NET JSON on System.Text.Json (#12805)
Browse files Browse the repository at this point in the history
* Implement System.Text.Json for Community.PowerToys.Run.Plugin.VSCodeWorkspaces (#11697)

* Implement System.Text.Json for Community.PowerToys.Run.Plugin.VSCodeWorkspaces

* Cleanup property names

* Implement System.Text.Json for Microsoft.PowerToys.Settings.UI (#11702)

* Implement System.Text.Json for Powerlauncher (#11699)

* Implement System.Text.Json for Wox.Infrastructure

* Implement System.Text.Json for Powerlauncher

* Implement System.Text.Json for Microsoft.Plugin.Folder

* Implement System.Text.Json for Wox.Plugin

* Remove Newtonsoft.Json from launcherInstallComponent

* Update properties with private setter
Format JSON output

* Serialize Get with private set property

* Implement System.Text.Json for ImageResizerUI (#11847)

* Implement System.Text.Json for ImageRezierUI

* Change Newtonsoft.Json.dll to System.Text.Json in ImageResizer

* Add  writefile to spelling whitelist

* Fix installer

* Fix bad merge

Co-authored-by: mykhailopylyp <17161067+mykhailopylyp@users.noreply.github.com>
  • Loading branch information
royvou and mykhailopylyp committed Aug 20, 2021
1 parent 44ef29c commit ea25bd9
Show file tree
Hide file tree
Showing 29 changed files with 241 additions and 113 deletions.
1 change: 1 addition & 0 deletions .github/actions/spell-check/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2380,6 +2380,7 @@ wprintf
wprp
wregex
WResize
writefile
wsf
wsh
wsl
Expand Down
6 changes: 3 additions & 3 deletions installer/PowerToysSetup/Product.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,6 @@
<Component Id="Module_ImageResizer" Guid="96E63289-759C-4A73-A56B-EE7429932F72" Win64="yes">
<File Source="$(var.BinX64Dir)modules\$(var.ImageResizerProjectName)\ImageResizer.exe" />
<File Source="$(var.BinX64Dir)modules\$(var.ImageResizerProjectName)\ImageResizerExt.dll" KeyPath="yes" />
<File Source="$(var.BinX64Dir)modules\$(var.ImageResizerProjectName)\Newtonsoft.Json.dll" />
<File Source="$(var.BinX64Dir)modules\$(var.ImageResizerProjectName)\ImageResizer.dll" />
<File Source="$(var.BinX64Dir)modules\$(var.ImageResizerProjectName)\ImageResizer.deps.json" />
<File Source="$(var.BinX64Dir)modules\$(var.ImageResizerProjectName)\ImageResizer.runtimeconfig.json" />
Expand All @@ -553,7 +552,8 @@
<File Id="Module_ImageResizer_Microsoft_Xaml_Behaviors" Source="$(var.BinX64Dir)modules\$(var.ImageResizerProjectName)\Microsoft.Xaml.Behaviors.dll" />
<File Id="ImageResizer_interop" Source="$(var.BinX64Dir)modules\$(var.ImageResizerProjectName)\PowerToysInterop.dll" />
<File Id="ImageResizer_System.IO.Abstractions.dll" Source="$(var.BinX64Dir)modules\$(var.ImageResizerProjectName)\System.IO.Abstractions.dll" />

<File Id="ImageResizer_System.Runtime.CompilerServices.Unsafe.dll" Source="$(var.BinX64Dir)modules\$(var.ImageResizerProjectName)\System.Runtime.CompilerServices.Unsafe.dll" />
<File Id="ImageResizer_System.Text.Encodings.Web.dll" Source="$(var.BinX64Dir)modules\$(var.ImageResizerProjectName)\System.Text.Encodings.Web.dll" />
<!-- VCRuntime -->
<?foreach File in vcruntime140.dll;vcruntime140_1.dll;concrt140.dll;msvcp140.dll;msvcp140_1.dll;msvcp140_2.dll;msvcp140_codecvt_ids.dll;vccorlib140.dll?>
<File Id="ImageResizer_$(var.File)" Source="$(var.RepoDir)installer\VCRuntime\$(var.File)" />
Expand Down Expand Up @@ -1078,7 +1078,7 @@

<Component Id="launcherInstallComponent" Directory="LauncherInstallFolder" Guid="5E688DB4-C522-4268-BA54-ED1CDFFE9DB6">
<File Source="$(var.BinX64Dir)modules\Launcher\Microsoft.Launcher.dll" />
<?foreach File in concrt140_app.dll;ICSharpCode.SharpZipLib.dll;JetBrains.Annotations.dll;Mages.Core.dll;Microsoft.Search.Interop.dll;Mono.Cecil.dll;Mono.Cecil.Mdb.dll;Mono.Cecil.Pdb.dll;Mono.Cecil.Rocks.dll;msvcp140_1_app.dll;msvcp140_2_app.dll;msvcp140_app.dll;Newtonsoft.Json.dll;NLog.dll;NLog.Extensions.Logging.dll;PowerLauncher.deps.json;PowerLauncher.dll;PowerLauncher.exe;Microsoft.Xaml.Behaviors.dll;System.Text.Json.dll;PowerLauncher.runtimeconfig.json;System.Data.OleDb.dll;UnitsNet.dll;vcamp140_app.dll;vccorlib140_app.dll;vcomp140_app.dll;vcruntime140_1_app.dll;vcruntime140_app.dll;Wox.Infrastructure.dll;Wox.Plugin.dll;PowerToysInterop.dll;ManagedTelemetry.dll;PowerLauncher.Telemetry.dll;Microsoft.Extensions.Configuration.Abstractions.dll;Microsoft.Extensions.Configuration.Binder.dll;Microsoft.Extensions.Configuration.dll;Microsoft.Extensions.DependencyInjection.Abstractions.dll;Microsoft.Extensions.DependencyInjection.dll;Microsoft.Extensions.Logging.Abstractions.dll;Microsoft.Extensions.Logging.dll;Microsoft.Extensions.Options.dll;Microsoft.Extensions.Primitives.dll;ControlzEx.dll;ManagedCommon.dll;System.IO.Abstractions.dll;Microsoft.PowerToys.Common.UI.dll;System.ServiceProcess.ServiceController.dll;Microsoft.Toolkit.Uwp.Notifications.dll;ModernWpf.Controls.dll;ModernWpf.dll;System.Runtime.CompilerServices.Unsafe.dll;System.Text.Encodings.Web.dll?>
<?foreach File in concrt140_app.dll;ICSharpCode.SharpZipLib.dll;JetBrains.Annotations.dll;Mages.Core.dll;Microsoft.Search.Interop.dll;Mono.Cecil.dll;Mono.Cecil.Mdb.dll;Mono.Cecil.Pdb.dll;Mono.Cecil.Rocks.dll;msvcp140_1_app.dll;msvcp140_2_app.dll;msvcp140_app.dll;NLog.dll;NLog.Extensions.Logging.dll;PowerLauncher.deps.json;PowerLauncher.dll;PowerLauncher.exe;Microsoft.Xaml.Behaviors.dll;System.Text.Json.dll;PowerLauncher.runtimeconfig.json;System.Data.OleDb.dll;UnitsNet.dll;vcamp140_app.dll;vccorlib140_app.dll;vcomp140_app.dll;vcruntime140_1_app.dll;vcruntime140_app.dll;Wox.Infrastructure.dll;Wox.Plugin.dll;PowerToysInterop.dll;ManagedTelemetry.dll;PowerLauncher.Telemetry.dll;Microsoft.Extensions.Configuration.Abstractions.dll;Microsoft.Extensions.Configuration.Binder.dll;Microsoft.Extensions.Configuration.dll;Microsoft.Extensions.DependencyInjection.Abstractions.dll;Microsoft.Extensions.DependencyInjection.dll;Microsoft.Extensions.Logging.Abstractions.dll;Microsoft.Extensions.Logging.dll;Microsoft.Extensions.Options.dll;Microsoft.Extensions.Primitives.dll;ControlzEx.dll;ManagedCommon.dll;System.IO.Abstractions.dll;Microsoft.PowerToys.Common.UI.dll;System.ServiceProcess.ServiceController.dll;Microsoft.Toolkit.Uwp.Notifications.dll;ModernWpf.Controls.dll;ModernWpf.dll;System.Runtime.CompilerServices.Unsafe.dll;System.Text.Encodings.Web.dll?>
<File Id="File_$(var.File)" Source="$(var.BinX64Dir)modules\launcher\$(var.File)" />
<?endforeach?>
<File Source="$(var.BinX64Dir)Settings\Microsoft.PowerToys.Settings.UI.Lib.dll" />
Expand Down
29 changes: 29 additions & 0 deletions src/modules/imageresizer/tests/Properties/SettingsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text.Json;
using ImageResizer.Models;
using ImageResizer.Test;
using Microsoft.VisualStudio.TestTools.UnitTesting;
Expand Down Expand Up @@ -347,6 +348,34 @@ public void ReloadRaisesPropertyChanged()
Assert.IsTrue(selectedSizeIndexChanged);
}

[TestMethod]
public void SystemTextJsonDeserializesCorrectly()
{
// Generated Settings file in 0.72
var defaultInput =
"{\r\n \"properties\": {\r\n \"imageresizer_selectedSizeIndex\": {\r\n \"value\": 1\r\n },\r\n \"imageresizer_shrinkOnly\": {\r\n \"value\": true\r\n },\r\n \"imageresizer_replace\": {\r\n \"value\": true\r\n },\r\n \"imageresizer_ignoreOrientation\": {\r\n \"value\": false\r\n },\r\n \"imageresizer_jpegQualityLevel\": {\r\n \"value\": 91\r\n },\r\n \"imageresizer_pngInterlaceOption\": {\r\n \"value\": 1\r\n },\r\n \"imageresizer_tiffCompressOption\": {\r\n \"value\": 1\r\n },\r\n \"imageresizer_fileName\": {\r\n \"value\": \"%1 %1 (%2)\"\r\n },\r\n \"imageresizer_sizes\": {\r\n \"value\": [\r\n {\r\n \"Id\": 0,\r\n \"ExtraBoxOpacity\": 100,\r\n \"EnableEtraBoxes\": true,\r\n \"name\": \"Small-NotDefault\",\r\n \"fit\": 1,\r\n \"width\": 854,\r\n \"height\": 480,\r\n \"unit\": 3\r\n },\r\n {\r\n \"Id\": 3,\r\n \"ExtraBoxOpacity\": 100,\r\n \"EnableEtraBoxes\": true,\r\n \"name\": \"Phone\",\r\n \"fit\": 1,\r\n \"width\": 320,\r\n \"height\": 568,\r\n \"unit\": 3\r\n }\r\n ]\r\n },\r\n \"imageresizer_keepDateModified\": {\r\n \"value\": false\r\n },\r\n \"imageresizer_fallbackEncoder\": {\r\n \"value\": \"19e4a5aa-5662-4fc5-a0c0-1758028e1057\"\r\n },\r\n \"imageresizer_customSize\": {\r\n \"value\": {\r\n \"Id\": 4,\r\n \"ExtraBoxOpacity\": 100,\r\n \"EnableEtraBoxes\": true,\r\n \"name\": \"custom\",\r\n \"fit\": 1,\r\n \"width\": 1024,\r\n \"height\": 640,\r\n \"unit\": 3\r\n }\r\n }\r\n },\r\n \"name\": \"ImageResizer\",\r\n \"version\": \"1\"\r\n}";

// Execute readFile/writefile twice and see if serialized string is still correct
var resultWrapper = JsonSerializer.Deserialize<SettingsWrapper>(defaultInput);
var serializedInput = JsonSerializer.Serialize(resultWrapper, new JsonSerializerOptions() { WriteIndented = true });
var resultWrapper2 = JsonSerializer.Deserialize<SettingsWrapper>(serializedInput);
var serializedInput2 = JsonSerializer.Serialize(resultWrapper2, new JsonSerializerOptions() { WriteIndented = true });

Assert.AreEqual(serializedInput, serializedInput2);
Assert.AreEqual("ImageResizer", resultWrapper2.Name);
Assert.AreEqual("1", resultWrapper2.Version);
Assert.IsNotNull(resultWrapper2.Properties);
Assert.IsTrue(resultWrapper2.Properties.ShrinkOnly);
Assert.IsTrue(resultWrapper2.Properties.Replace);
Assert.AreEqual(91, resultWrapper2.Properties.JpegQualityLevel);
Assert.AreEqual(1, (int)resultWrapper2.Properties.PngInterlaceOption);
Assert.AreEqual(1, (int)resultWrapper2.Properties.TiffCompressOption);
Assert.AreEqual("%1 %1 (%2)", resultWrapper2.Properties.FileName);
Assert.AreEqual(2, resultWrapper2.Properties.Sizes.Count);
Assert.IsFalse(resultWrapper2.Properties.KeepDateModified);
Assert.AreEqual("Small-NotDefault", resultWrapper2.Properties.Sizes[0].Name);
}

[ClassCleanup]
public static void ClassCleanup()
{
Expand Down
2 changes: 1 addition & 1 deletion src/modules/imageresizer/ui/ImageResizerUI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,13 @@
</PackageReference>
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.19" />
<PackageReference Include="ModernWpfUI" Version="0.9.4" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="System.IO.Abstractions">
<Version>12.2.5</Version>
</PackageReference>
<PackageReference Include="System.Text.Json" Version="5.0.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\interop\PowerToysInterop.vcxproj" />
Expand Down
3 changes: 2 additions & 1 deletion src/modules/imageresizer/ui/Models/CustomSize.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/

using System.Text.Json.Serialization;
using ImageResizer.Properties;
using Newtonsoft.Json;

namespace ImageResizer.Models
{
Expand All @@ -16,6 +16,7 @@ public override string Name
set { /* no-op */ }
}

[JsonConstructor]
public CustomSize(ResizeFit fit, double width, double height, ResizeUnit unit)
{
Fit = fit;
Expand Down
15 changes: 7 additions & 8 deletions src/modules/imageresizer/ui/Models/ResizeSize.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
// Copyright (c) Brice Lambson
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/

using System.Collections.Generic;
using System.Diagnostics;
using System.Text.Json.Serialization;
using ImageResizer.Helpers;
using ImageResizer.Properties;
using Newtonsoft.Json;

namespace ImageResizer.Models
{
[JsonObject(MemberSerialization.OptIn)]
public class ResizeSize : Observable
{
private static readonly IDictionary<string, string> _tokens = new Dictionary<string, string>
Expand Down Expand Up @@ -41,14 +40,14 @@ public ResizeSize()
{
}

[JsonProperty(PropertyName = "name")]
[JsonPropertyName("name")]
public virtual string Name
{
get => _name;
set => Set(ref _name, ReplaceTokens(value));
}

[JsonProperty(PropertyName = "fit")]
[JsonPropertyName("fit")]
public ResizeFit Fit
{
get => _fit;
Expand All @@ -63,14 +62,14 @@ public ResizeFit Fit
}
}

[JsonProperty(PropertyName = "width")]
[JsonPropertyName("width")]
public double Width
{
get => _width;
set => Set(ref _width, value);
}

[JsonProperty(PropertyName = "height")]
[JsonPropertyName("height")]
public double Height
{
get => _height;
Expand All @@ -86,7 +85,7 @@ public bool ShowHeight
public bool HasAuto
=> Width == 0 || Height == 0 || double.IsNaN(Width) || double.IsNaN(Height);

[JsonProperty(PropertyName = "unit")]
[JsonPropertyName("unit")]
public ResizeUnit Unit
{
get => _unit;
Expand Down
71 changes: 33 additions & 38 deletions src/modules/imageresizer/ui/Properties/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,14 @@
using System.ComponentModel;
using System.Globalization;
using System.IO.Abstractions;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Windows.Media.Imaging;
using ImageResizer.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;

namespace ImageResizer.Properties
{
[JsonObject(MemberSerialization.OptIn)]
public sealed partial class Settings : IDataErrorInfo, INotifyPropertyChanged
{
private static readonly IFileSystem _fileSystem = new FileSystem();
Expand Down Expand Up @@ -63,6 +61,7 @@ public Settings()
AllSizes = new AllSizesCollection(this);
}

[JsonIgnore]
public IEnumerable<ResizeSize> AllSizes { get; set; }

// Using OrdinalIgnoreCase since this is internal and used for comparison with symbols
Expand All @@ -78,6 +77,7 @@ public string FileNameFormat
.Replace("%5", "{4}", StringComparison.OrdinalIgnoreCase)
.Replace("%6", "{5}", StringComparison.OrdinalIgnoreCase));

[JsonIgnore]
public ResizeSize SelectedSize
{
get => SelectedSizeIndex >= 0 && SelectedSizeIndex < Sizes.Count
Expand Down Expand Up @@ -222,6 +222,7 @@ public void Reset()

private static Settings defaultInstance = new Settings();

[JsonIgnore]
public static Settings Default
{
get
Expand All @@ -231,7 +232,8 @@ public static Settings Default
}
}

[JsonProperty(PropertyName = "imageresizer_selectedSizeIndex")]
[JsonConverter(typeof(WrappedJsonValueConverter))]
[JsonPropertyName("imageresizer_selectedSizeIndex")]
public int SelectedSizeIndex
{
get => _selectedSizeIndex;
Expand All @@ -242,7 +244,8 @@ public int SelectedSizeIndex
}
}

[JsonProperty(PropertyName = "imageresizer_shrinkOnly")]
[JsonConverter(typeof(WrappedJsonValueConverter))]
[JsonPropertyName("imageresizer_shrinkOnly")]
public bool ShrinkOnly
{
get => _shrinkOnly;
Expand All @@ -253,7 +256,8 @@ public bool ShrinkOnly
}
}

[JsonProperty(PropertyName = "imageresizer_replace")]
[JsonConverter(typeof(WrappedJsonValueConverter))]
[JsonPropertyName("imageresizer_replace")]
public bool Replace
{
get => _replace;
Expand All @@ -264,7 +268,8 @@ public bool Replace
}
}

[JsonProperty(PropertyName = "imageresizer_ignoreOrientation")]
[JsonConverter(typeof(WrappedJsonValueConverter))]
[JsonPropertyName("imageresizer_ignoreOrientation")]
public bool IgnoreOrientation
{
get => _ignoreOrientation;
Expand All @@ -275,7 +280,8 @@ public bool IgnoreOrientation
}
}

[JsonProperty(PropertyName = "imageresizer_jpegQualityLevel")]
[JsonConverter(typeof(WrappedJsonValueConverter))]
[JsonPropertyName("imageresizer_jpegQualityLevel")]
public int JpegQualityLevel
{
get => _jpegQualityLevel;
Expand All @@ -286,7 +292,8 @@ public int JpegQualityLevel
}
}

[JsonProperty(PropertyName = "imageresizer_pngInterlaceOption")]
[JsonConverter(typeof(WrappedJsonValueConverter))]
[JsonPropertyName("imageresizer_pngInterlaceOption")]
public PngInterlaceOption PngInterlaceOption
{
get => _pngInterlaceOption;
Expand All @@ -297,7 +304,8 @@ public PngInterlaceOption PngInterlaceOption
}
}

[JsonProperty(PropertyName = "imageresizer_tiffCompressOption")]
[JsonConverter(typeof(WrappedJsonValueConverter))]
[JsonPropertyName("imageresizer_tiffCompressOption")]
public TiffCompressOption TiffCompressOption
{
get => _tiffCompressOption;
Expand All @@ -308,7 +316,8 @@ public TiffCompressOption TiffCompressOption
}
}

[JsonProperty(PropertyName = "imageresizer_fileName")]
[JsonConverter(typeof(WrappedJsonValueConverter))]
[JsonPropertyName("imageresizer_fileName")]
public string FileName
{
get => _fileName;
Expand All @@ -324,10 +333,13 @@ public string FileName
}
}

[JsonProperty(PropertyName = "imageresizer_sizes")]
[JsonInclude]
[JsonConverter(typeof(WrappedJsonValueConverter))]
[JsonPropertyName("imageresizer_sizes")]
public ObservableCollection<ResizeSize> Sizes { get; private set; }

[JsonProperty(PropertyName = "imageresizer_keepDateModified")]
[JsonConverter(typeof(WrappedJsonValueConverter))]
[JsonPropertyName("imageresizer_keepDateModified")]
public bool KeepDateModified
{
get => _keepDateModified;
Expand All @@ -338,8 +350,9 @@ public bool KeepDateModified
}
}

[JsonProperty(PropertyName = "imageresizer_fallbackEncoder")]
public System.Guid FallbackEncoder
[JsonConverter(typeof(WrappedJsonValueConverter))]
[JsonPropertyName("imageresizer_fallbackEncoder")]
public Guid FallbackEncoder
{
get => _fallbackEncoder;
set
Expand All @@ -349,7 +362,8 @@ public System.Guid FallbackEncoder
}
}

[JsonProperty(PropertyName = "imageresizer_customSize")]
[JsonConverter(typeof(WrappedJsonValueConverter))]
[JsonPropertyName("imageresizer_customSize")]
public CustomSize CustomSize
{
get => _customSize;
Expand All @@ -372,18 +386,7 @@ private void NotifyPropertyChanged([System.Runtime.CompilerServices.CallerMember
public void Save()
{
_jsonMutex.WaitOne();
string jsonData = "{\"version\":\"1.0\",\"name\":\"ImageResizer\",\"properties\":";
string tempJsonData = JsonConvert.SerializeObject(this);
JObject tempSettings = JObject.Parse(tempJsonData);

// Replace the <Value> of the property with { "value": <Value> } to be consistent with PowerToys
foreach (var property in tempSettings)
{
tempSettings[property.Key] = new JObject { { "value", property.Value } };
}

jsonData += tempSettings.ToString(Formatting.None);
jsonData += "}";
string jsonData = JsonSerializer.Serialize(new SettingsWrapper() { Properties = this });

// Create directory if it doesn't exist
IFileInfo file = _fileSystem.FileInfo.FromFileName(SettingsPath);
Expand All @@ -405,15 +408,7 @@ public void Reload()
}

string jsonData = _fileSystem.File.ReadAllText(SettingsPath);
JObject imageResizerSettings = JObject.Parse(jsonData);

// Replace the { "value": <Value> } with <Value> to match the Settings object format
foreach (var property in (JObject)imageResizerSettings["properties"])
{
imageResizerSettings["properties"][property.Key] = property.Value["value"];
}

Settings jsonSettings = JsonConvert.DeserializeObject<Settings>(imageResizerSettings["properties"].ToString(), new JsonSerializerSettings() { ObjectCreationHandling = ObjectCreationHandling.Replace });
Settings jsonSettings = JsonSerializer.Deserialize<SettingsWrapper>(jsonData)?.Properties;

// Needs to be called on the App UI thread as the properties are bound to the UI.
App.Current.Dispatcher.Invoke(() =>
Expand Down

0 comments on commit ea25bd9

Please sign in to comment.