Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V14: Migrate Newtonsoft to System.Text in value converters #15728

Merged
merged 19 commits into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
87abe9e
Force system text json for IJSonSerializer
nikolajlauridsen Feb 9, 2024
320d784
Migrate ColorPickerValueConverter
nikolajlauridsen Feb 9, 2024
0d496a8
Move ColorPickerValueConverter
nikolajlauridsen Feb 9, 2024
764e664
Clean up ColorPickerValueConverter
nikolajlauridsen Feb 12, 2024
a41341f
Remove obsoleted property editors
nikolajlauridsen Feb 12, 2024
9d62162
Migrate FlexibleDropdownPropertyValueConverter to System.Text.Json
nikolajlauridsen Feb 12, 2024
034b430
Use IJsonSerializer instead and move the value converter to Core
nikolajlauridsen Feb 12, 2024
2bf0048
Migrate ImageCropperValueConverter to System.Text.Json
nikolajlauridsen Feb 12, 2024
0bb2010
Inject jsonserializer in test and obsolete old constructor
nikolajlauridsen Feb 14, 2024
c17d697
Migrate JsonValueConverter to System.Text.Json
nikolajlauridsen Feb 14, 2024
ee242c6
Merge branch 'v14/dev' into v14/feature/migrate-property-editors-to-s…
nikolajlauridsen Feb 16, 2024
dce6177
Remove ContextualConfigurationEditorJsonSerializer
nikolajlauridsen Feb 16, 2024
ce8c556
Remove JsonNetSerializer
nikolajlauridsen Feb 16, 2024
e49b69d
Remove obsolete DeserializeSubset from JsonSerializer interface
nikolajlauridsen Feb 16, 2024
6fe077f
Fix FlexibleDropdownPropertyValueConverter
nikolajlauridsen Feb 16, 2024
9a37056
Update test JSON to be actual valid json
nikolajlauridsen Feb 19, 2024
45f2b88
Update more test json
nikolajlauridsen Feb 19, 2024
1815879
Update time format to be valid
nikolajlauridsen Feb 19, 2024
834cb78
Add JsonPropertyName to models
nikolajlauridsen Feb 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/Umbraco.Core/Models/ContentEditing/ContentItemDisplay.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using System.Text.Json.Serialization;
using Umbraco.Cms.Core.Routing;

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

[DataMember(Name = "template")]
[JsonPropertyName("template")]
nikolajlauridsen marked this conversation as resolved.
Show resolved Hide resolved
public string? TemplateAlias { get; set; }

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

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

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

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

Expand Down
5 changes: 5 additions & 0 deletions src/Umbraco.Core/Models/ContentEditing/Language.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using System.Text.Json.Serialization;

namespace Umbraco.Cms.Core.Models.ContentEditing;

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

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

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

[DataMember(Name = "isDefault")]
[JsonPropertyName("isDefault")]
public bool IsDefault { get; set; }

[DataMember(Name = "isMandatory")]
[JsonPropertyName("isMandatory")]
public bool IsMandatory { get; set; }

[DataMember(Name = "fallbackIsoCode")]
[JsonPropertyName("fallbackIsoCode")]
public string? FallbackIsoCode { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Text.Json.Serialization;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.Serialization;
using Umbraco.Extensions;

namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters;

[DefaultPropertyValueConverter]
public class ColorPickerValueConverter : PropertyValueConverterBase
{
private readonly IJsonSerializer _jsonSerializer;

public ColorPickerValueConverter(IJsonSerializer jsonSerializer)
{
_jsonSerializer = jsonSerializer;
}

public override bool IsConverter(IPublishedPropertyType propertyType)
=> propertyType.EditorAlias.InvariantEquals(Constants.PropertyEditors.Aliases.ColorPicker);

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

if (source == null)
if (source is null)
{
return useLabel ? null : string.Empty;
}

var ssource = source.ToString()!;
if (ssource.DetectIsJson())
var value = source.ToString()!;
if (value.DetectIsJson())
{
try
{
JObject? jo = JsonConvert.DeserializeObject<JObject>(ssource);
if (useLabel)
{
return new PickedColor(jo!["value"]!.ToString(), jo["label"]!.ToString());
}

return jo!["value"]!.ToString();
}
catch
{
/* not json finally */
}
PickedColor? convertedValue = _jsonSerializer.Deserialize<PickedColor>(value);
return useLabel ? convertedValue : convertedValue?.Color;
}

// This seems to be something old old where it may not be json at all.
if (useLabel)
{
return new PickedColor(ssource, ssource);
return new PickedColor(value, value);
}

return ssource;
return value;
}

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

[JsonPropertyName("value")]
public string Color { get; }

public string Label { get; }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,38 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.

using Newtonsoft.Json;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.Serialization;

namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters;

[DefaultPropertyValueConverter]
public class FlexibleDropdownPropertyValueConverter : PropertyValueConverterBase
{
private readonly IJsonSerializer _jsonSerializer;

public FlexibleDropdownPropertyValueConverter(IJsonSerializer jsonSerializer) => _jsonSerializer = jsonSerializer;

public override bool IsConverter(IPublishedPropertyType propertyType) =>
propertyType.EditorAlias.Equals(Constants.PropertyEditors.Aliases.DropDownListFlexible);

public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview)
{
if (source == null)
if (source is null)
{
return Array.Empty<string>();
}

return JsonConvert.DeserializeObject<string[]>(source.ToString()!) ?? Array.Empty<string>();
var sourceString = source.ToString();

return string.IsNullOrWhiteSpace(sourceString)
? Array.Empty<string>()
: _jsonSerializer.Deserialize<string[]>(source.ToString()!) ?? Array.Empty<string>();
}

public override object? ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview)
{
if (inter == null)
if (inter is null)
{
return null;
}
Expand Down
3 changes: 0 additions & 3 deletions src/Umbraco.Core/Serialization/IJsonSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,4 @@ public interface IJsonSerializer
string Serialize(object? input);

T? Deserialize<T>(string input);

[Obsolete("This will be removed in v13")]
T? DeserializeSubset<T>(string input, string key);
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ public static IUmbracoBuilder AddCoreInitialServices(this IUmbracoBuilder builde

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

builder.Services.AddSingleton<IJsonSerializer, ContextualJsonSerializer>();
builder.Services.AddSingleton<IConfigurationEditorJsonSerializer, ContextualConfigurationEditorJsonSerializer>();
builder.Services.AddSingleton<IJsonSerializer, SystemTextJsonSerializer>();
builder.Services.AddSingleton<IConfigurationEditorJsonSerializer, SystemTextConfigurationEditorJsonSerializer>();
builder.Services.AddSingleton<IMenuItemCollectionFactory, MenuItemCollectionFactory>();

// register database builder
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.

using System.Globalization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Models.DeliveryApi;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.PropertyEditors.DeliveryApi;
using Umbraco.Cms.Core.Serialization;
using Umbraco.Extensions;

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

private readonly ILogger<ImageCropperValueConverter> _logger;

public ImageCropperValueConverter(ILogger<ImageCropperValueConverter> logger) => _logger = logger;
public ImageCropperValueConverter(ILogger<ImageCropperValueConverter> logger, IJsonSerializer jsonSerializer)
{
_logger = logger;
_jsonSerializer = jsonSerializer;
}

[Obsolete("Use the constructor specifying all dependencies, scheduled for removal in V16")]
public ImageCropperValueConverter(ILogger<ImageCropperValueConverter> logger)
: this(logger, StaticServiceProvider.Instance.GetRequiredService<IJsonSerializer>())
{
}

/// <inheritdoc />
public override bool IsConverter(IPublishedPropertyType propertyType)
Expand All @@ -52,9 +59,7 @@ public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType
ImageCropperValue? value;
try
{
value = JsonConvert.DeserializeObject<ImageCropperValue>(
sourceString,
_imageCropperValueJsonSerializerSettings);
value = _jsonSerializer.Deserialize<ImageCropperValue>(sourceString);
}
catch (Exception ex)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.

using System.Text.Json;
using System.Text.Json.Nodes;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.PropertyEditors.DeliveryApi;
using Umbraco.Extensions;
Expand Down Expand Up @@ -46,8 +45,9 @@ public JsonValueConverter(PropertyEditorCollection propertyEditors, ILogger<Json
&& editor.GetValueEditor().ValueType.InvariantEquals(ValueTypes.Json)
&& _excludedPropertyEditors.Contains(propertyType.EditorAlias) == false;

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

public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType)
=> PropertyCacheLevel.Element;
Expand All @@ -65,8 +65,7 @@ public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType
{
try
{
var obj = JsonConvert.DeserializeObject(sourceString);
return obj;
return JsonDocument.Parse(sourceString);
}
catch (Exception ex)
{
Expand All @@ -85,7 +84,7 @@ public Type GetDeliveryApiPropertyValueType(IPublishedPropertyType propertyType)
=> typeof(JsonNode);

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

This file was deleted.