Apply changes from #11805 and #11806 to v9 (#11904)

* Apply changes from #11805 and #11806 to v9

* Update documentation and cleanup code styling
This commit is contained in:
Ronald Barendse
2022-01-26 12:22:05 +01:00
committed by GitHub
parent 72533d29c8
commit 4d4aff4c67
16 changed files with 159 additions and 150 deletions

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Logging;
@@ -75,8 +75,7 @@ namespace Umbraco.Extensions
var updatedTags = currentTags.Union(trimmedTags).ToArray();
var updatedValue = updatedTags.Length == 0 ? null : serializer.Serialize(updatedTags);
property.SetValue(updatedValue, culture); // json array
break;
property.SetValue(serializer.Serialize(currentTags.Union(trimmedTags).ToArray()), culture); // json array
break;
}
}
else
@@ -88,7 +87,8 @@ namespace Umbraco.Extensions
break;
case TagsStorageType.Json:
property.SetValue(serializer.Serialize(trimmedTags), culture); // json array
var updatedValue = trimmedTags.Length == 0 ? null : serializer.Serialize(trimmedTags);
property.SetValue(updatedValue, culture); // json array
break;
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
@@ -149,84 +149,90 @@ namespace Umbraco.Cms.Core.PropertyEditors
public virtual bool IsReadOnly => false;
/// <summary>
/// Used to try to convert the string value to the correct CLR type based on the DatabaseDataType specified for this value editor
/// Used to try to convert the string value to the correct CLR type based on the <see cref="ValueType" /> specified for this value editor.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
/// <param name="value">The value.</param>
/// <returns>
/// The result of the conversion attempt.
/// </returns>
/// <exception cref="System.ArgumentOutOfRangeException">ValueType was out of range.</exception>
internal Attempt<object> TryConvertValueToCrlType(object value)
{
// if (value is JValue)
// value = value.ToString();
//this is a custom check to avoid any errors, if it's a string and it's empty just make it null
// Ensure empty string values are converted to null
if (value is string s && string.IsNullOrWhiteSpace(s))
{
value = null;
}
// Ensure JSON is serialized properly (without indentation or converted to null when empty)
if (value is not null && ValueType.InvariantEquals(ValueTypes.Json))
{
var jsonValue = _jsonSerializer.Serialize(value);
if (jsonValue.DetectIsEmptyJson())
{
value = null;
}
else
{
value = jsonValue;
}
}
// Convert the string to a known type
Type valueType;
//convert the string to a known type
switch (ValueTypes.ToStorageType(ValueType))
{
case ValueStorageType.Ntext:
case ValueStorageType.Nvarchar:
valueType = typeof(string);
break;
case ValueStorageType.Integer:
//ensure these are nullable so we can return a null if required
//NOTE: This is allowing type of 'long' because I think json.net will deserialize a numerical value as long
// instead of int. Even though our db will not support this (will get truncated), we'll at least parse to this.
case ValueStorageType.Integer:
// Ensure these are nullable so we can return a null if required
// NOTE: This is allowing type of 'long' because I think JSON.NEt will deserialize a numerical value as long instead of int
// Even though our DB will not support this (will get truncated), we'll at least parse to this
valueType = typeof(long?);
//if parsing is successful, we need to return as an Int, we're only dealing with long's here because of json.net, we actually
//don't support long values and if we return a long value it will get set as a 'long' on the Property.Value (object) and then
//when we compare the values for dirty tracking we'll be comparing an int -> long and they will not match.
// If parsing is successful, we need to return as an int, we're only dealing with long's here because of JSON.NET,
// we actually don't support long values and if we return a long value, it will get set as a 'long' on the Property.Value (object) and then
// when we compare the values for dirty tracking we'll be comparing an int -> long and they will not match.
var result = value.TryConvertTo(valueType);
return result.Success && result.Result != null
? Attempt<object>.Succeed((int)(long)result.Result)
: result;
case ValueStorageType.Decimal:
//ensure these are nullable so we can return a null if required
// Ensure these are nullable so we can return a null if required
valueType = typeof(decimal?);
break;
case ValueStorageType.Date:
//ensure these are nullable so we can return a null if required
// Ensure these are nullable so we can return a null if required
valueType = typeof(DateTime?);
break;
default:
throw new ArgumentOutOfRangeException();
throw new ArgumentOutOfRangeException("ValueType was out of range.");
}
return value.TryConvertTo(valueType);
}
/// <summary>
/// A method to deserialize the string value that has been saved in the content editor
/// to an object to be stored in the database.
/// </summary>
/// <param name="editorValue"></param>
/// <param name="currentValue">
/// The current value that has been persisted to the database for this editor. This value may be useful for
/// how the value then get's deserialized again to be re-persisted. In most cases it will probably not be used.
/// </param>
/// <param name="languageId"></param>
/// <param name="segment"></param>
/// <returns></returns>
/// <remarks>
/// By default this will attempt to automatically convert the string value to the value type supplied by ValueType.
///
/// If overridden then the object returned must match the type supplied in the ValueType, otherwise persisting the
/// value to the DB will fail when it tries to validate the value type.
/// </remarks>
/// <summary>
/// A method to deserialize the string value that has been saved in the content editor to an object to be stored in the database.
/// </summary>
/// <param name="editorValue">The value returned by the editor.</param>
/// <param name="currentValue">The current value that has been persisted to the database for this editor. This value may be useful for how the value then get's deserialized again to be re-persisted. In most cases it will probably not be used.</param>
/// <returns>The value that gets persisted to the database.</returns>
/// <remarks>
/// By default this will attempt to automatically convert the string value to the value type supplied by ValueType.
/// If overridden then the object returned must match the type supplied in the ValueType, otherwise persisting the
/// value to the DB will fail when it tries to validate the value type.
/// </remarks>
public virtual object FromEditor(ContentPropertyData editorValue, object currentValue)
{
//if it's json but it's empty json, then return null
if (ValueType.InvariantEquals(ValueTypes.Json) && editorValue.Value != null && editorValue.Value.ToString().DetectIsEmptyJson())
{
return null;
}
var result = TryConvertValueToCrlType(editorValue.Value);
if (result.Success == false)
{
@@ -238,64 +244,71 @@ namespace Umbraco.Cms.Core.PropertyEditors
}
/// <summary>
/// A method used to format the database value to a value that can be used by the editor
/// A method used to format the database value to a value that can be used by the editor.
/// </summary>
/// <param name="property"></param>
/// <param name="dataTypeService"></param>
/// <param name="culture"></param>
/// <param name="segment"></param>
/// <param name="property">The property.</param>
/// <param name="culture">The culture.</param>
/// <param name="segment">The segment.</param>
/// <returns></returns>
/// <exception cref="System.ArgumentOutOfRangeException">ValueType was out of range.</exception>
/// <remarks>
/// The object returned will automatically be serialized into json notation. For most property editors
/// the value returned is probably just a string but in some cases a json structure will be returned.
/// The object returned will automatically be serialized into JSON notation. For most property editors
/// the value returned is probably just a string, but in some cases a JSON structure will be returned.
/// </remarks>
public virtual object ToEditor(IProperty property, string culture = null, string segment = null)
{
var val = property.GetValue(culture, segment);
if (val == null) return string.Empty;
var value = property.GetValue(culture, segment);
if (value == null)
{
return string.Empty;
}
switch (ValueTypes.ToStorageType(ValueType))
{
case ValueStorageType.Ntext:
case ValueStorageType.Nvarchar:
//if it is a string type, we will attempt to see if it is json stored data, if it is we'll try to convert
//to a real json object so we can pass the true json object directly to angular!
var asString = val.ToString();
if (asString.DetectIsJson())
// If it is a string type, we will attempt to see if it is JSON stored data, if it is we'll try to convert
// to a real JSON object so we can pass the true JSON object directly to Angular!
var stringValue = value as string ?? value.ToString();
if (stringValue.DetectIsJson())
{
try
{
var json = _jsonSerializer.Deserialize<dynamic>(asString);
return json;
return _jsonSerializer.Deserialize<dynamic>(stringValue);
}
catch
{
//swallow this exception, we thought it was json but it really isn't so continue returning a string
// Swallow this exception, we thought it was JSON but it really isn't so continue returning a string
}
}
return asString;
return stringValue;
case ValueStorageType.Integer:
case ValueStorageType.Decimal:
//Decimals need to be formatted with invariant culture (dots, not commas)
//Anything else falls back to ToString()
var decim = val.TryConvertTo<decimal>();
return decim.Success
? decim.Result.ToString(NumberFormatInfo.InvariantInfo)
: val.ToString();
// Decimals need to be formatted with invariant culture (dots, not commas)
// Anything else falls back to ToString()
var decimalValue = value.TryConvertTo<decimal>();
return decimalValue.Success
? decimalValue.Result.ToString(NumberFormatInfo.InvariantInfo)
: value.ToString();
case ValueStorageType.Date:
var date = val.TryConvertTo<DateTime?>();
if (date.Success == false || date.Result == null)
var dateValue = value.TryConvertTo<DateTime?>();
if (dateValue.Success == false || dateValue.Result == null)
{
return string.Empty;
}
//Dates will be formatted as yyyy-MM-dd HH:mm:ss
return date.Result.Value.ToIsoString();
// Dates will be formatted as yyyy-MM-dd HH:mm:ss
return dateValue.Result.Value.ToIsoString();
default:
throw new ArgumentOutOfRangeException();
throw new ArgumentOutOfRangeException("ValueType was out of range.");
}
}
// TODO: the methods below should be replaced by proper property value convert ToXPath usage!
/// <summary>

View File

@@ -1,12 +1,10 @@
// Copyright (c) Umbraco.
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Media;
using Umbraco.Cms.Core.Models;
@@ -153,7 +151,8 @@ namespace Umbraco.Cms.Core.PropertyEditors
public override object ToEditor(IProperty property, string culture = null, string segment = null)
{
var val = property.GetValue(culture, segment)?.ToString();
if (val.IsNullOrWhiteSpace()) return string.Empty;
if (val.IsNullOrWhiteSpace())
return string.Empty;
var grid = DeserializeGridValue(val, out var rtes, out _);
@@ -199,7 +198,7 @@ namespace Umbraco.Cms.Core.PropertyEditors
_richTextPropertyValueEditor.GetReferences(x.Value)))
yield return umbracoEntityReference;
foreach (var umbracoEntityReference in mediaValues.Where(x=>x.Value.HasValues)
foreach (var umbracoEntityReference in mediaValues.Where(x => x.Value.HasValues)
.SelectMany(x => _mediaPickerPropertyValueEditor.GetReferences(x.Value["udi"])))
yield return umbracoEntityReference;
}

View File

@@ -208,6 +208,7 @@ namespace Umbraco.Cms.Core.PropertyEditors
{
continue;
}
var sourcePath = _mediaFileManager.FileSystem.GetRelativePath(src);
var copyPath = _mediaFileManager.CopyFile(notification.Copy, property.PropertyType, sourcePath);
jo["src"] = _mediaFileManager.FileSystem.GetUrl(copyPath);
@@ -273,10 +274,8 @@ namespace Umbraco.Cms.Core.PropertyEditors
// the property value will be the file source eg '/media/23454/hello.jpg' and we
// are fixing that anomaly here - does not make any sense at all but... bah...
src = svalue;
property.SetValue(JsonConvert.SerializeObject(new
{
src = svalue
}, Formatting.None), pvalue.Culture, pvalue.Segment);
property.SetValue(JsonConvert.SerializeObject(new { src = svalue }, Formatting.None), pvalue.Culture, pvalue.Segment);
}
else
{

View File

@@ -86,31 +86,42 @@ namespace Umbraco.Cms.Core.PropertyEditors
/// </remarks>
public override object FromEditor(ContentPropertyData editorValue, object currentValue)
{
// get the current path
// Get the current path
var currentPath = string.Empty;
try
{
var svalue = currentValue as string;
var currentJson = string.IsNullOrWhiteSpace(svalue) ? null : JObject.Parse(svalue);
if (currentJson != null && currentJson["src"] != null)
currentPath = currentJson["src"].Value<string>();
if (currentJson != null && currentJson.TryGetValue("src", out var src))
{
currentPath = src.Value<string>();
}
}
catch (Exception ex)
{
// for some reason the value is invalid so continue as if there was no value there
// For some reason the value is invalid so continue as if there was no value there
_logger.LogWarning(ex, "Could not parse current db value to a JObject.");
}
if (string.IsNullOrWhiteSpace(currentPath) == false)
currentPath = _mediaFileManager.FileSystem.GetRelativePath(currentPath);
// get the new json and path
JObject editorJson = null;
// Get the new JSON and file path
var editorFile = string.Empty;
if (editorValue.Value != null)
if (editorValue.Value is JObject editorJson)
{
editorJson = editorValue.Value as JObject;
if (editorJson != null && editorJson["src"] != null)
// Populate current file
if (editorJson["src"] != null)
{
editorFile = editorJson["src"].Value<string>();
}
// Clean up redundant/default data
ImageCropperValue.Prune(editorJson);
}
else
{
editorJson = null;
}
// ensure we have the required guids
@@ -138,7 +149,7 @@ namespace Umbraco.Cms.Core.PropertyEditors
return null; // clear
}
return editorJson?.ToString(); // unchanged
return editorJson?.ToString(Formatting.None); // unchanged
}
// process the file
@@ -159,7 +170,7 @@ namespace Umbraco.Cms.Core.PropertyEditors
// update json and return
if (editorJson == null) return null;
editorJson["src"] = filepath == null ? string.Empty : _mediaFileManager.FileSystem.GetUrl(filepath);
return editorJson.ToString();
return editorJson.ToString(Formatting.None);
}
private string ProcessFile(ContentPropertyFile file, Guid cuid, Guid puid)
@@ -186,7 +197,6 @@ namespace Umbraco.Cms.Core.PropertyEditors
return filepath;
}
public override string ConvertDbToString(IPropertyType propertyType, object value)
{
if (value == null || string.IsNullOrEmpty(value.ToString()))
@@ -205,7 +215,7 @@ namespace Umbraco.Cms.Core.PropertyEditors
{
src = val,
crops = crops
},new JsonSerializerSettings()
}, new JsonSerializerSettings()
{
Formatting = Formatting.None,
NullValueHandling = NullValueHandling.Ignore

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.IO;
@@ -157,7 +157,6 @@ namespace Umbraco.Cms.Core.PropertyEditors
}
}
/// <summary>
/// Model/DTO that represents the JSON that the MediaPicker3 stores.
/// </summary>
@@ -176,7 +175,6 @@ namespace Umbraco.Cms.Core.PropertyEditors
[DataMember(Name = "focalPoint")]
public ImageCropperValue.ImageCropperFocalPoint FocalPoint { get; set; }
/// <summary>
/// Applies the configuration to ensure only valid crops are kept and have the correct width/height.
/// </summary>
@@ -214,9 +212,6 @@ namespace Umbraco.Cms.Core.PropertyEditors
/// Removes redundant crop data/default focal point.
/// </summary>
/// <param name="value">The media with crops DTO.</param>
/// <returns>
/// The cleaned up value.
/// </returns>
/// <remarks>
/// Because the DTO uses the same JSON keys as the image cropper value for crops and focal point, we can re-use the prune method.
/// </remarks>

View File

@@ -57,7 +57,7 @@ namespace Umbraco.Cms.Core.PropertyEditors
try
{
var links = JsonConvert.DeserializeObject<List<MultiUrlPickerValueEditor.LinkDto>>(value);
var links = JsonConvert.DeserializeObject<List<LinkDto>>(value);
var documentLinks = links.FindAll(link => link.Udi != null && link.Udi.EntityType == Constants.UdiEntityType.Document);
var mediaLinks = links.FindAll(link => link.Udi != null && link.Udi.EntityType == Constants.UdiEntityType.Media);
@@ -158,11 +158,13 @@ namespace Umbraco.Cms.Core.PropertyEditors
{
var links = JsonConvert.DeserializeObject<List<LinkDisplay>>(value);
if (links.Count == 0)
{
return null;
}
return JsonConvert.SerializeObject(
from link in links
select new MultiUrlPickerValueEditor.LinkDto
select new LinkDto
{
Name = link.Name,
QueryString = link.QueryString,

View File

@@ -1,14 +1,12 @@
// Copyright (c) Umbraco.
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using Umbraco.Cms.Core.Exceptions;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Editors;

View File

@@ -1,4 +1,4 @@
// Copyright (c) Umbraco.
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System;
@@ -65,7 +65,6 @@ namespace Umbraco.Cms.Core.PropertyEditors
}
var values = json.Select(item => item.Value<string>()).ToArray();
if (values.Length == 0)
{
return null;

View File

@@ -1,4 +1,4 @@
// Copyright (c) Umbraco.
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System;
@@ -105,7 +105,9 @@ namespace Umbraco.Cms.Core.PropertyEditors
var rows = _nestedContentValues.GetPropertyValues(propertyValue);
if (rows.Count == 0)
{
return null;
}
foreach (var row in rows.ToList())
{
@@ -141,8 +143,6 @@ namespace Umbraco.Cms.Core.PropertyEditors
#endregion
#region Convert database // editor
// note: there is NO variant support here

View File

@@ -1,4 +1,4 @@
// Copyright (c) Umbraco.
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System;
@@ -148,7 +148,9 @@ namespace Umbraco.Cms.Core.PropertyEditors
public override object FromEditor(ContentPropertyData editorValue, object currentValue)
{
if (editorValue.Value == null)
{
return null;
}
var userId = _backOfficeSecurityAccessor?.BackOfficeSecurity?.CurrentUser?.Id ?? Constants.Security.SuperUserId;

View File

@@ -1,4 +1,4 @@
// Copyright (c) Umbraco.
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System;

View File

@@ -21,14 +21,14 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters
/// </summary>
[JsonConverter(typeof(NoTypeConverterJsonConverter<ImageCropperValue>))]
[TypeConverter(typeof(ImageCropperValueTypeConverter))]
[DataContract(Name="imageCropDataSet")]
[DataContract(Name = "imageCropDataSet")]
public class ImageCropperValue : IHtmlEncodedString, IEquatable<ImageCropperValue>
{
/// <summary>
/// Gets or sets the value source image.
/// </summary>
[DataMember(Name="src")]
public string Src { get; set;}
[DataMember(Name = "src")]
public string Src { get; set; }
/// <summary>
/// Gets or sets the value focal point.
@@ -44,9 +44,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters
/// <inheritdoc />
public override string ToString()
{
return Crops != null ? (Crops.Any() ? JsonConvert.SerializeObject(this) : Src) : string.Empty;
}
=> HasCrops() || HasFocalPoint() ? JsonConvert.SerializeObject(this, Formatting.None) : Src;
/// <inheritdoc />
public string ToHtmlString() => Src;
@@ -178,12 +176,10 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters
/// Removes redundant crop data/default focal point.
/// </summary>
/// <param name="value">The image cropper value.</param>
/// <returns>
/// The cleaned up value.
/// </returns>
public static void Prune(JObject value)
{
if (value is null) throw new ArgumentNullException(nameof(value));
if (value is null)
throw new ArgumentNullException(nameof(value));
if (value.TryGetValue("crops", out var crops))
{
@@ -252,8 +248,8 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters
// properties are, practically, readonly
// ReSharper disable NonReadonlyMemberInGetHashCode
var hashCode = Src?.GetHashCode() ?? 0;
hashCode = (hashCode*397) ^ (FocalPoint?.GetHashCode() ?? 0);
hashCode = (hashCode*397) ^ (Crops?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ (FocalPoint?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ (Crops?.GetHashCode() ?? 0);
return hashCode;
// ReSharper restore NonReadonlyMemberInGetHashCode
}
@@ -298,7 +294,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters
{
// properties are, practically, readonly
// ReSharper disable NonReadonlyMemberInGetHashCode
return (Left.GetHashCode()*397) ^ Top.GetHashCode();
return (Left.GetHashCode() * 397) ^ Top.GetHashCode();
// ReSharper restore NonReadonlyMemberInGetHashCode
}
}
@@ -352,9 +348,9 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters
// properties are, practically, readonly
// ReSharper disable NonReadonlyMemberInGetHashCode
var hashCode = Alias?.GetHashCode() ?? 0;
hashCode = (hashCode*397) ^ Width;
hashCode = (hashCode*397) ^ Height;
hashCode = (hashCode*397) ^ (Coordinates?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ Width;
hashCode = (hashCode * 397) ^ Height;
hashCode = (hashCode * 397) ^ (Coordinates?.GetHashCode() ?? 0);
return hashCode;
// ReSharper restore NonReadonlyMemberInGetHashCode
}
@@ -409,9 +405,9 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters
// properties are, practically, readonly
// ReSharper disable NonReadonlyMemberInGetHashCode
var hashCode = X1.GetHashCode();
hashCode = (hashCode*397) ^ Y1.GetHashCode();
hashCode = (hashCode*397) ^ X2.GetHashCode();
hashCode = (hashCode*397) ^ Y2.GetHashCode();
hashCode = (hashCode * 397) ^ Y1.GetHashCode();
hashCode = (hashCode * 397) ^ X2.GetHashCode();
hashCode = (hashCode * 397) ^ Y2.GetHashCode();
return hashCode;
// ReSharper restore NonReadonlyMemberInGetHashCode
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
@@ -15,25 +15,20 @@ namespace Umbraco.Cms.Infrastructure.Serialization
{
new StringEnumConverter()
},
Formatting = Formatting.None
Formatting = Formatting.None,
NullValueHandling = NullValueHandling.Ignore
};
public string Serialize(object input)
{
return JsonConvert.SerializeObject(input, JsonSerializerSettings);
}
public T Deserialize<T>(string input)
{
return JsonConvert.DeserializeObject<T>(input, JsonSerializerSettings);
}
public string Serialize(object input) => JsonConvert.SerializeObject(input, JsonSerializerSettings);
public T Deserialize<T>(string input) => JsonConvert.DeserializeObject<T>(input, JsonSerializerSettings);
public T DeserializeSubset<T>(string input, string key)
{
if (key == null) throw new ArgumentNullException(nameof(key));
var root = JsonConvert.DeserializeObject<JObject>(input);
var jToken = root.SelectToken(key);
var root = Deserialize<JObject>(input);
var jToken = root?.SelectToken(key);
return jToken switch
{

View File

@@ -1,4 +1,4 @@
using System;
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -20,6 +20,7 @@ namespace Umbraco.Cms.Infrastructure.Serialization
{
return reader.Value;
}
// Load JObject from stream
JObject jObject = JObject.Load(reader);
return jObject.ToString(Formatting.None);

View File

@@ -21,7 +21,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.PropertyEditors
private readonly JsonSerializerSettings _serializerSettings = new JsonSerializerSettings
{
Formatting = Formatting.None,
NullValueHandling = NullValueHandling.Ignore,
NullValueHandling = NullValueHandling.Ignore
};
private const string ContentGuid1 = "036ce82586a64dfba2d523a99ed80f58";