Skip to content

Commit

Permalink
V14: Migrate Newtonsoft to System.Text in value converters (#15728)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
nikolajlauridsen committed Feb 22, 2024
1 parent 58bc868 commit 7735552
Show file tree
Hide file tree
Showing 45 changed files with 117 additions and 361 deletions.
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")]
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.

0 comments on commit 7735552

Please sign in to comment.