Merge commit '94d525d88f713b36419f28bfda4d82ee68637d83' into v9/dev
# Conflicts: # build/NuSpecs/UmbracoCms.Web.nuspec # src/Umbraco.Core/Composing/Current.cs # src/Umbraco.Core/Persistence/NPocoDatabaseExtensions-Bulk.cs # src/Umbraco.Core/Runtime/CoreRuntime.cs # src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs # src/Umbraco.Infrastructure/Persistence/NPocoDatabaseExtensions.cs # src/Umbraco.Infrastructure/Persistence/UmbracoDatabase.cs # src/Umbraco.Persistence.SqlCe/SqlCeSyntaxProvider.cs # src/Umbraco.PublishedCache.NuCache/DataSource/BTree.cs # src/Umbraco.PublishedCache.NuCache/DataSource/ContentCacheDataModel.cs # src/Umbraco.PublishedCache.NuCache/DataSource/ContentCacheDataSerializationResult.cs # src/Umbraco.PublishedCache.NuCache/DataSource/ContentCacheDataSerializerEntityType.cs # src/Umbraco.PublishedCache.NuCache/DataSource/ContentData.cs # src/Umbraco.PublishedCache.NuCache/DataSource/ContentNestedData.cs # src/Umbraco.PublishedCache.NuCache/DataSource/CultureVariation.cs # src/Umbraco.PublishedCache.NuCache/DataSource/IContentCacheDataSerializer.cs # src/Umbraco.PublishedCache.NuCache/DataSource/IContentCacheDataSerializerFactory.cs # src/Umbraco.PublishedCache.NuCache/DataSource/IDictionaryOfPropertyDataSerializer.cs # src/Umbraco.PublishedCache.NuCache/DataSource/JsonContentNestedDataSerializer.cs # src/Umbraco.PublishedCache.NuCache/DataSource/JsonContentNestedDataSerializerFactory.cs # src/Umbraco.PublishedCache.NuCache/DataSource/LazyCompressedString.cs # src/Umbraco.PublishedCache.NuCache/DataSource/MsgPackContentNestedDataSerializer.cs # src/Umbraco.PublishedCache.NuCache/DataSource/MsgPackContentNestedDataSerializerFactory.cs # src/Umbraco.PublishedCache.NuCache/DataSource/PropertyData.cs # src/Umbraco.PublishedCache.NuCache/NuCacheSerializerComponent.cs # src/Umbraco.PublishedCache.NuCache/NuCacheSerializerComposer.cs # src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentTypeServiceVariantsTests.cs # src/Umbraco.Tests/App.config # src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs # src/Umbraco.Tests/PublishedContent/NuCacheTests.cs # src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/da.xml # src/Umbraco.Web.UI/web.Template.Debug.config # src/Umbraco.Web.UI/web.Template.config # src/Umbraco.Web/Composing/ModuleInjector.cs # src/Umbraco.Web/Editors/NuCacheStatusController.cs # src/Umbraco.Web/PublishedCache/NuCache/DataSource/ContentNestedData.cs # src/Umbraco.Web/PublishedCache/NuCache/DataSource/DatabaseDataSource.cs # src/Umbraco.Web/PublishedCache/NuCache/NuCacheComposer.cs # src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs # src/Umbraco.Web/Runtime/WebRuntime.cs
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.Serialization
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// When applied to a string or string collection field will ensure the deserialized strings are interned
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Borrowed from https://stackoverflow.com/a/34906004/694494
|
||||
/// On the same page an interesting approach of using a local intern pool https://stackoverflow.com/a/39605620/694494 which re-uses .NET System.Xml.NameTable
|
||||
/// </remarks>
|
||||
public class AutoInterningStringConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
// CanConvert is not called when a converter is applied directly to a property.
|
||||
throw new NotImplementedException($"{nameof(AutoInterningStringConverter)} should not be used globally");
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.Null)
|
||||
return null;
|
||||
// Check is in case the value is a non-string literal such as an integer.
|
||||
var s = reader.TokenType == JsonToken.String
|
||||
? string.Intern((string)reader.Value)
|
||||
: string.Intern((string)JToken.Load(reader));
|
||||
return s;
|
||||
}
|
||||
|
||||
public override bool CanWrite => false;
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// When applied to a dictionary with a string key, will ensure the deserialized string keys are interned
|
||||
/// </summary>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
/// <remarks>
|
||||
/// borrowed from https://stackoverflow.com/a/36116462/694494
|
||||
/// </remarks>
|
||||
public class AutoInterningStringKeyCaseInsensitiveDictionaryConverter<TValue> : CaseInsensitiveDictionaryConverter<TValue>
|
||||
{
|
||||
public AutoInterningStringKeyCaseInsensitiveDictionaryConverter()
|
||||
{
|
||||
}
|
||||
public AutoInterningStringKeyCaseInsensitiveDictionaryConverter(StringComparer comparer) : base(comparer)
|
||||
{
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.StartObject)
|
||||
{
|
||||
var dictionary = new Dictionary<string, TValue>();
|
||||
while (reader.Read())
|
||||
{
|
||||
switch (reader.TokenType)
|
||||
{
|
||||
case JsonToken.PropertyName:
|
||||
var key = string.Intern(reader.Value.ToString());
|
||||
|
||||
if (!reader.Read())
|
||||
throw new Exception("Unexpected end when reading object.");
|
||||
|
||||
var v = serializer.Deserialize<TValue>(reader);
|
||||
dictionary[key] = v;
|
||||
break;
|
||||
case JsonToken.Comment:
|
||||
break;
|
||||
case JsonToken.EndObject:
|
||||
return dictionary;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json.Converters;
|
||||
@@ -14,12 +14,24 @@ namespace Umbraco.Cms.Infrastructure.Serialization
|
||||
/// </example>
|
||||
public class CaseInsensitiveDictionaryConverter<T> : CustomCreationConverter<IDictionary>
|
||||
{
|
||||
private readonly StringComparer _comparer;
|
||||
|
||||
public CaseInsensitiveDictionaryConverter()
|
||||
: this(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
}
|
||||
|
||||
public CaseInsensitiveDictionaryConverter(StringComparer comparer)
|
||||
{
|
||||
_comparer = comparer ?? throw new ArgumentNullException(nameof(comparer));
|
||||
}
|
||||
|
||||
public override bool CanWrite => false;
|
||||
|
||||
public override bool CanRead => true;
|
||||
|
||||
public override bool CanConvert(Type objectType) => typeof(IDictionary<string,T>).IsAssignableFrom(objectType);
|
||||
|
||||
public override IDictionary Create(Type objectType) => new Dictionary<string, T>(StringComparer.OrdinalIgnoreCase);
|
||||
public override IDictionary Create(Type objectType) => new Dictionary<string, T>(_comparer);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user