Skip to content

Commit 7735552

Browse files
V14: Migrate Newtonsoft to System.Text in value converters (#15728)
* Force system text json for IJSonSerializer * Migrate ColorPickerValueConverter * Move ColorPickerValueConverter * Clean up ColorPickerValueConverter * Remove obsoleted property editors * Migrate FlexibleDropdownPropertyValueConverter to System.Text.Json * Use IJsonSerializer instead and move the value converter to Core * Migrate ImageCropperValueConverter to System.Text.Json * Inject jsonserializer in test and obsolete old constructor * Migrate JsonValueConverter to System.Text.Json * Remove ContextualConfigurationEditorJsonSerializer * Remove JsonNetSerializer * Remove obsolete DeserializeSubset from JsonSerializer interface * Fix FlexibleDropdownPropertyValueConverter * Update test JSON to be actual valid json * Update more test json * Update time format to be valid * Add JsonPropertyName to models
1 parent 58bc868 commit 7735552

File tree

45 files changed

+117
-361
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+117
-361
lines changed

src/Umbraco.Core/Models/ContentEditing/ContentItemDisplay.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.ComponentModel;
22
using System.ComponentModel.DataAnnotations;
33
using System.Runtime.Serialization;
4+
using System.Text.Json.Serialization;
45
using Umbraco.Cms.Core.Routing;
56

67
namespace Umbraco.Cms.Core.Models.ContentEditing;
@@ -135,6 +136,7 @@ public ContentItemDisplay()
135136
public DateTime UpdateDate { get; set; }
136137

137138
[DataMember(Name = "template")]
139+
[JsonPropertyName("template")]
138140
public string? TemplateAlias { get; set; }
139141

140142
[DataMember(Name = "templateId")]
@@ -172,6 +174,7 @@ public ContentItemDisplay()
172174
public bool IsBlueprint { get; set; }
173175

174176
[DataMember(Name = "apps")]
177+
[JsonPropertyName("apps")]
175178
public IEnumerable<ContentApp> ContentApps { get; set; }
176179

177180
/// <summary>
@@ -200,6 +203,7 @@ public ContentItemDisplay()
200203
/// A collection of extra data that is available for this specific entity/entity type
201204
/// </summary>
202205
[DataMember(Name = "metaData")]
206+
[JsonPropertyName("metaData")]
203207
[ReadOnly(true)]
204208
public IDictionary<string, object> AdditionalData { get; private set; } = new Dictionary<string, object>();
205209

@@ -213,6 +217,7 @@ public ContentItemDisplay()
213217
/// NOTE: The ProperCase is important because when we return ModeState normally it will always be proper case.
214218
/// </remarks>
215219
[DataMember(Name = "ModelState")]
220+
[JsonPropertyName("ModelState")]
216221
[ReadOnly(true)]
217222
public IDictionary<string, object> Errors { get; set; }
218223

src/Umbraco.Core/Models/ContentEditing/Language.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.ComponentModel.DataAnnotations;
22
using System.Runtime.Serialization;
3+
using System.Text.Json.Serialization;
34

45
namespace Umbraco.Cms.Core.Models.ContentEditing;
56

@@ -10,18 +11,22 @@ public class Language
1011
public int Id { get; set; }
1112

1213
[DataMember(Name = "culture", IsRequired = true)]
14+
[JsonPropertyName("culture")]
1315
[Required(AllowEmptyStrings = false)]
1416
public string IsoCode { get; set; } = null!;
1517

1618
[DataMember(Name = "name")]
1719
public string? Name { get; set; }
1820

1921
[DataMember(Name = "isDefault")]
22+
[JsonPropertyName("isDefault")]
2023
public bool IsDefault { get; set; }
2124

2225
[DataMember(Name = "isMandatory")]
26+
[JsonPropertyName("isMandatory")]
2327
public bool IsMandatory { get; set; }
2428

2529
[DataMember(Name = "fallbackIsoCode")]
30+
[JsonPropertyName("fallbackIsoCode")]
2631
public string? FallbackIsoCode { get; set; }
2732
}
Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
// Copyright (c) Umbraco.
22
// See LICENSE for more details.
33

4-
using Newtonsoft.Json;
5-
using Newtonsoft.Json.Linq;
4+
using System.Text.Json.Serialization;
65
using Umbraco.Cms.Core.Models.PublishedContent;
6+
using Umbraco.Cms.Core.Serialization;
77
using Umbraco.Extensions;
88

99
namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters;
1010

1111
[DefaultPropertyValueConverter]
1212
public class ColorPickerValueConverter : PropertyValueConverterBase
1313
{
14+
private readonly IJsonSerializer _jsonSerializer;
15+
16+
public ColorPickerValueConverter(IJsonSerializer jsonSerializer)
17+
{
18+
_jsonSerializer = jsonSerializer;
19+
}
20+
1421
public override bool IsConverter(IPublishedPropertyType propertyType)
1522
=> propertyType.EditorAlias.InvariantEquals(Constants.PropertyEditors.Aliases.ColorPicker);
1623

@@ -24,36 +31,25 @@ public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType
2431
{
2532
var useLabel = UseLabel(propertyType);
2633

27-
if (source == null)
34+
if (source is null)
2835
{
2936
return useLabel ? null : string.Empty;
3037
}
3138

32-
var ssource = source.ToString()!;
33-
if (ssource.DetectIsJson())
39+
var value = source.ToString()!;
40+
if (value.DetectIsJson())
3441
{
35-
try
36-
{
37-
JObject? jo = JsonConvert.DeserializeObject<JObject>(ssource);
38-
if (useLabel)
39-
{
40-
return new PickedColor(jo!["value"]!.ToString(), jo["label"]!.ToString());
41-
}
42-
43-
return jo!["value"]!.ToString();
44-
}
45-
catch
46-
{
47-
/* not json finally */
48-
}
42+
PickedColor? convertedValue = _jsonSerializer.Deserialize<PickedColor>(value);
43+
return useLabel ? convertedValue : convertedValue?.Color;
4944
}
5045

46+
// This seems to be something old old where it may not be json at all.
5147
if (useLabel)
5248
{
53-
return new PickedColor(ssource, ssource);
49+
return new PickedColor(value, value);
5450
}
5551

56-
return ssource;
52+
return value;
5753
}
5854

5955
private bool UseLabel(IPublishedPropertyType propertyType) => ConfigurationEditor
@@ -67,6 +63,7 @@ public PickedColor(string color, string label)
6763
Label = label;
6864
}
6965

66+
[JsonPropertyName("value")]
7067
public string Color { get; }
7168

7269
public string Label { get; }
Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,38 @@
11
// Copyright (c) Umbraco.
22
// See LICENSE for more details.
33

4-
using Newtonsoft.Json;
54
using Umbraco.Cms.Core.Models.PublishedContent;
5+
using Umbraco.Cms.Core.Serialization;
66

77
namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters;
88

99
[DefaultPropertyValueConverter]
1010
public class FlexibleDropdownPropertyValueConverter : PropertyValueConverterBase
1111
{
12+
private readonly IJsonSerializer _jsonSerializer;
13+
14+
public FlexibleDropdownPropertyValueConverter(IJsonSerializer jsonSerializer) => _jsonSerializer = jsonSerializer;
15+
1216
public override bool IsConverter(IPublishedPropertyType propertyType) =>
1317
propertyType.EditorAlias.Equals(Constants.PropertyEditors.Aliases.DropDownListFlexible);
1418

1519
public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview)
1620
{
17-
if (source == null)
21+
if (source is null)
1822
{
1923
return Array.Empty<string>();
2024
}
2125

22-
return JsonConvert.DeserializeObject<string[]>(source.ToString()!) ?? Array.Empty<string>();
26+
var sourceString = source.ToString();
27+
28+
return string.IsNullOrWhiteSpace(sourceString)
29+
? Array.Empty<string>()
30+
: _jsonSerializer.Deserialize<string[]>(source.ToString()!) ?? Array.Empty<string>();
2331
}
2432

2533
public override object? ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview)
2634
{
27-
if (inter == null)
35+
if (inter is null)
2836
{
2937
return null;
3038
}

src/Umbraco.Core/Serialization/IJsonSerializer.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,4 @@ public interface IJsonSerializer
55
string Serialize(object? input);
66

77
T? Deserialize<T>(string input);
8-
9-
[Obsolete("This will be removed in v13")]
10-
T? DeserializeSubset<T>(string input, string key);
118
}

src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ public static IUmbracoBuilder AddCoreInitialServices(this IUmbracoBuilder builde
125125

126126
builder.Services.AddScoped<IHttpScopeReference, HttpScopeReference>();
127127

128-
builder.Services.AddSingleton<IJsonSerializer, ContextualJsonSerializer>();
129-
builder.Services.AddSingleton<IConfigurationEditorJsonSerializer, ContextualConfigurationEditorJsonSerializer>();
128+
builder.Services.AddSingleton<IJsonSerializer, SystemTextJsonSerializer>();
129+
builder.Services.AddSingleton<IConfigurationEditorJsonSerializer, SystemTextConfigurationEditorJsonSerializer>();
130130
builder.Services.AddSingleton<IMenuItemCollectionFactory, MenuItemCollectionFactory>();
131131

132132
// register database builder

src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/ImageCropperValueConverter.cs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
// Copyright (c) Umbraco.
22
// See LICENSE for more details.
33

4-
using System.Globalization;
4+
using Microsoft.Extensions.DependencyInjection;
55
using Microsoft.Extensions.Logging;
6-
using Newtonsoft.Json;
6+
using Umbraco.Cms.Core.DependencyInjection;
77
using Umbraco.Cms.Core.Models.DeliveryApi;
88
using Umbraco.Cms.Core.Models.PublishedContent;
99
using Umbraco.Cms.Core.PropertyEditors.DeliveryApi;
10+
using Umbraco.Cms.Core.Serialization;
1011
using Umbraco.Extensions;
1112

1213
namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters;
@@ -17,15 +18,21 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters;
1718
[DefaultPropertyValueConverter(typeof(JsonValueConverter))]
1819
public class ImageCropperValueConverter : PropertyValueConverterBase, IDeliveryApiPropertyValueConverter
1920
{
20-
private static readonly JsonSerializerSettings _imageCropperValueJsonSerializerSettings = new()
21-
{
22-
Culture = CultureInfo.InvariantCulture,
23-
FloatParseHandling = FloatParseHandling.Decimal,
24-
};
21+
private readonly IJsonSerializer _jsonSerializer;
2522

2623
private readonly ILogger<ImageCropperValueConverter> _logger;
2724

28-
public ImageCropperValueConverter(ILogger<ImageCropperValueConverter> logger) => _logger = logger;
25+
public ImageCropperValueConverter(ILogger<ImageCropperValueConverter> logger, IJsonSerializer jsonSerializer)
26+
{
27+
_logger = logger;
28+
_jsonSerializer = jsonSerializer;
29+
}
30+
31+
[Obsolete("Use the constructor specifying all dependencies, scheduled for removal in V16")]
32+
public ImageCropperValueConverter(ILogger<ImageCropperValueConverter> logger)
33+
: this(logger, StaticServiceProvider.Instance.GetRequiredService<IJsonSerializer>())
34+
{
35+
}
2936

3037
/// <inheritdoc />
3138
public override bool IsConverter(IPublishedPropertyType propertyType)
@@ -52,9 +59,7 @@ public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType
5259
ImageCropperValue? value;
5360
try
5461
{
55-
value = JsonConvert.DeserializeObject<ImageCropperValue>(
56-
sourceString,
57-
_imageCropperValueJsonSerializerSettings);
62+
value = _jsonSerializer.Deserialize<ImageCropperValue>(sourceString);
5863
}
5964
catch (Exception ex)
6065
{

src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/JsonValueConverter.cs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
// Copyright (c) Umbraco.
22
// See LICENSE for more details.
33

4+
using System.Text.Json;
45
using System.Text.Json.Nodes;
56
using Microsoft.Extensions.Logging;
6-
using Newtonsoft.Json;
7-
using Newtonsoft.Json.Linq;
87
using Umbraco.Cms.Core.Models.PublishedContent;
98
using Umbraco.Cms.Core.PropertyEditors.DeliveryApi;
109
using Umbraco.Extensions;
@@ -46,8 +45,9 @@ public override bool IsConverter(IPublishedPropertyType propertyType) =>
4645
&& editor.GetValueEditor().ValueType.InvariantEquals(ValueTypes.Json)
4746
&& _excludedPropertyEditors.Contains(propertyType.EditorAlias) == false;
4847

48+
// We return a JsonDocument here because it's readonly and faster than JsonNode.
4949
public override Type GetPropertyValueType(IPublishedPropertyType propertyType)
50-
=> typeof(JToken);
50+
=> typeof(JsonDocument);
5151

5252
public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType)
5353
=> PropertyCacheLevel.Element;
@@ -65,8 +65,7 @@ public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType
6565
{
6666
try
6767
{
68-
var obj = JsonConvert.DeserializeObject(sourceString);
69-
return obj;
68+
return JsonDocument.Parse(sourceString);
7069
}
7170
catch (Exception ex)
7271
{
@@ -85,7 +84,7 @@ public Type GetDeliveryApiPropertyValueType(IPublishedPropertyType propertyType)
8584
=> typeof(JsonNode);
8685

8786
public object? ConvertIntermediateToDeliveryApiObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview, bool expanding)
88-
=> inter is JObject jObject
89-
? JsonNode.Parse(jObject.ToString())
90-
: null;
87+
=> inter is not JsonDocument jsonDocument
88+
? null
89+
: JsonNode.Parse(jsonDocument.RootElement.ToString());
9190
}

src/Umbraco.Infrastructure/Serialization/ConfigurationEditorJsonSerializer.cs

Lines changed: 0 additions & 42 deletions
This file was deleted.

0 commit comments

Comments
 (0)