From 578e1317a08b68eb0f9df0945fe671ad5de4dd19 Mon Sep 17 00:00:00 2001 From: nzdev <834725+nzdev@users.noreply.github.com> Date: Wed, 1 Jul 2020 17:19:56 +1200 Subject: [PATCH 1/2] Introduce IContentNestedDataSerializer to allow injecting a custom serializer for nucache --- .../PublishedContent/NuCacheChildrenTests.cs | 5 +- .../PublishedContent/NuCacheTests.cs | 5 +- .../Scoping/ScopedNuCacheTests.cs | 6 +- .../ContentTypeServiceVariantsTests.cs | 7 +- .../NuCache/DataSource/ContentNestedData.cs | 2 +- .../NuCache/DataSource/CultureVariation.cs | 2 +- .../NuCache/DataSource/DatabaseDataSource.cs | 31 ++-- .../IContentNestedDataSerializer.cs | 14 ++ .../JsonContentNestedDataSerializer.cs | 31 ++++ ...opertiesJsonContentNestedDataSerializer.cs | 157 ++++++++++++++++++ .../NuCache/DataSource/PropertyData.cs | 2 +- .../PublishedCache/NuCache/NuCacheComposer.cs | 3 + .../NuCache/PublishedSnapshotService.cs | 6 +- src/Umbraco.Web/Umbraco.Web.csproj | 2 + 14 files changed, 245 insertions(+), 28 deletions(-) create mode 100644 src/Umbraco.Web/PublishedCache/NuCache/DataSource/IContentNestedDataSerializer.cs create mode 100644 src/Umbraco.Web/PublishedCache/NuCache/DataSource/JsonContentNestedDataSerializer.cs create mode 100644 src/Umbraco.Web/PublishedCache/NuCache/DataSource/MappedPropertiesJsonContentNestedDataSerializer.cs diff --git a/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs index 834d211994..fef096498c 100644 --- a/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs +++ b/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs @@ -37,6 +37,7 @@ namespace Umbraco.Tests.PublishedContent private ContentType _contentTypeInvariant; private ContentType _contentTypeVariant; private TestDataSource _source; + private IContentNestedDataSerializer _contentNestedDataSerializer; [TearDown] public void Teardown() @@ -134,6 +135,7 @@ namespace Umbraco.Tests.PublishedContent // create a data source for NuCache _source = new TestDataSource(kits()); + _contentNestedDataSerializer = new JsonContentNestedDataSerializer(); // at last, create the complete NuCache snapshot service! var options = new PublishedSnapshotServiceOptions { IgnoreLocalDb = true }; @@ -155,7 +157,8 @@ namespace Umbraco.Tests.PublishedContent globalSettings, Mock.Of(), Mock.Of(), - new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() })); + new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), + _contentNestedDataSerializer); // invariant is the current default _variationAccesor.VariationContext = new VariationContext(); diff --git a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs index 0e05e6baad..792ccc8529 100644 --- a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs +++ b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs @@ -33,6 +33,7 @@ namespace Umbraco.Tests.PublishedContent { private IPublishedSnapshotService _snapshotService; private IVariationContextAccessor _variationAccesor; + private IContentNestedDataSerializer _contentNestedDataSerializer; private ContentType _contentType; private PropertyType _propertyType; @@ -114,6 +115,7 @@ namespace Umbraco.Tests.PublishedContent // create a data source for NuCache var dataSource = new TestDataSource(kit); + _contentNestedDataSerializer = new JsonContentNestedDataSerializer(); var runtime = Mock.Of(); Mock.Get(runtime).Setup(x => x.Level).Returns(RuntimeLevel.Run); @@ -201,7 +203,8 @@ namespace Umbraco.Tests.PublishedContent globalSettings, Mock.Of(), Mock.Of(), - new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() })); + new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), + _contentNestedDataSerializer); // invariant is the current default _variationAccesor.VariationContext = new VariationContext(); diff --git a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs index c7c403b260..5f72947382 100644 --- a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs @@ -82,6 +82,7 @@ namespace Umbraco.Tests.Scoping var mediaRepository = Mock.Of(); var memberRepository = Mock.Of(); + var nestedContentDataSerializer = new JsonContentNestedDataSerializer(); return new PublishedSnapshotService( options, null, @@ -95,11 +96,12 @@ namespace Umbraco.Tests.Scoping ScopeProvider, documentRepository, mediaRepository, memberRepository, DefaultCultureAccessor, - new DatabaseDataSource(), + new DatabaseDataSource(nestedContentDataSerializer), Factory.GetInstance(), Factory.GetInstance(), Mock.Of(), - new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() })); + new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), + nestedContentDataSerializer); } protected UmbracoContext GetUmbracoContextNu(string url, int templateId = 1234, RouteData routeData = null, bool setSingleton = false, IUmbracoSettingsSection umbracoSettings = null, IEnumerable urlProviders = null) diff --git a/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs b/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs index 9391b7442f..938b14c3a9 100644 --- a/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs +++ b/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs @@ -53,6 +53,8 @@ namespace Umbraco.Tests.Services var mediaRepository = Mock.Of(); var memberRepository = Mock.Of(); + var nestedContentDataSerializer = new JsonContentNestedDataSerializer(); + return new PublishedSnapshotService( options, null, @@ -66,11 +68,12 @@ namespace Umbraco.Tests.Services ScopeProvider, documentRepository, mediaRepository, memberRepository, DefaultCultureAccessor, - new DatabaseDataSource(), + new DatabaseDataSource(nestedContentDataSerializer), Factory.GetInstance(), Factory.GetInstance(), Mock.Of(), - new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() })); + new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), + nestedContentDataSerializer); } public class LocalServerMessenger : ServerMessengerBase diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/ContentNestedData.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/ContentNestedData.cs index ec5424ad9a..5f3edc4aa9 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/ContentNestedData.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/ContentNestedData.cs @@ -7,7 +7,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource /// /// The content item 1:M data that is serialized to JSON /// - internal class ContentNestedData + public class ContentNestedData { //dont serialize empty properties [JsonProperty("pd")] diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/CultureVariation.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/CultureVariation.cs index 57ffbba34e..b59e8c403c 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/CultureVariation.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/CultureVariation.cs @@ -6,7 +6,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource /// /// Represents the culture variation information on a content item /// - internal class CultureVariation + public class CultureVariation { [JsonProperty("nm")] public string Name { get; set; } diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/DatabaseDataSource.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/DatabaseDataSource.cs index 694dac04df..80cfabd470 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/DatabaseDataSource.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/DatabaseDataSource.cs @@ -20,7 +20,15 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource // provides efficient database access for NuCache internal class DatabaseDataSource : IDataSource { + + private const int PageSize = 500; + private readonly IContentNestedDataSerializer _contentNestedDataSerializer; + + internal DatabaseDataSource(IContentNestedDataSerializer contentNestedDataSerializer) + { + _contentNestedDataSerializer = contentNestedDataSerializer; + } // we want arrays, we want them all loaded, not an enumerable @@ -198,7 +206,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource yield return CreateMediaNodeKit(row); } - private static ContentNodeKit CreateContentNodeKit(ContentSourceDto dto) + private ContentNodeKit CreateContentNodeKit(ContentSourceDto dto) { ContentData d = null; ContentData p = null; @@ -213,7 +221,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource } else { - var nested = DeserializeNestedData(dto.EditData); + var nested = _contentNestedDataSerializer.Deserialize(dto.EditData); d = new ContentData { @@ -240,7 +248,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource } else { - var nested = DeserializeNestedData(dto.PubData); + var nested = _contentNestedDataSerializer.Deserialize(dto.PubData); p = new ContentData { @@ -271,12 +279,12 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource return s; } - private static ContentNodeKit CreateMediaNodeKit(ContentSourceDto dto) + private ContentNodeKit CreateMediaNodeKit(ContentSourceDto dto) { if (dto.EditData == null) throw new Exception("No data for media " + dto.Id); - var nested = DeserializeNestedData(dto.EditData); + var nested = _contentNestedDataSerializer.Deserialize(dto.EditData); var p = new ContentData { @@ -303,17 +311,6 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource return s; } - private static ContentNestedData DeserializeNestedData(string data) - { - // by default JsonConvert will deserialize our numeric values as Int64 - // which is bad, because they were Int32 in the database - take care - - var settings = new JsonSerializerSettings - { - Converters = new List { new ForceInt32Converter() } - }; - - return JsonConvert.DeserializeObject(data, settings); - } + } } diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/IContentNestedDataSerializer.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/IContentNestedDataSerializer.cs new file mode 100644 index 0000000000..d9e2702d08 --- /dev/null +++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/IContentNestedDataSerializer.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Umbraco.Web.PublishedCache.NuCache.DataSource +{ + public interface IContentNestedDataSerializer + { + ContentNestedData Deserialize(string data); + string Serialize(ContentNestedData nestedData); + } +} diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/JsonContentNestedDataSerializer.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/JsonContentNestedDataSerializer.cs new file mode 100644 index 0000000000..4ef63c09fb --- /dev/null +++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/JsonContentNestedDataSerializer.cs @@ -0,0 +1,31 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Umbraco.Core.Serialization; + +namespace Umbraco.Web.PublishedCache.NuCache.DataSource +{ + internal class JsonContentNestedDataSerializer : IContentNestedDataSerializer + { + public ContentNestedData Deserialize(string data) + { + // by default JsonConvert will deserialize our numeric values as Int64 + // which is bad, because they were Int32 in the database - take care + + var settings = new JsonSerializerSettings + { + Converters = new List { new ForceInt32Converter() } + }; + + return JsonConvert.DeserializeObject(data, settings); + } + + public string Serialize(ContentNestedData nestedData) + { + return JsonConvert.SerializeObject(nestedData); + } + } +} diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/MappedPropertiesJsonContentNestedDataSerializer.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/MappedPropertiesJsonContentNestedDataSerializer.cs new file mode 100644 index 0000000000..4919404e11 --- /dev/null +++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/MappedPropertiesJsonContentNestedDataSerializer.cs @@ -0,0 +1,157 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Umbraco.Core.Serialization; + +namespace Umbraco.Web.PublishedCache.NuCache.DataSource +{ + public class MappedPropertiesJsonContentNestedDataSerializer : IContentNestedDataSerializer + { + private readonly IDictionary _serializeMap; + private readonly IDictionary _deserializeMap; + + + /// + /// Constructor + /// + /// Map for PropertData properties + /// + public MappedPropertiesJsonContentNestedDataSerializer(IDictionary serializeMap, IDictionary deserializeMap) + { + _serializeMap = serializeMap; + _deserializeMap = deserializeMap; + } + + public (string mappedName, bool isCompressed) ToSerializedProperty(string name) + { + if(_serializeMap.TryGetValue(name,out PropertyMap map)) + { + return (map.To,map.IsCompressed); + } + return (name,false); + } + public (string mappedName, bool isCompressed) ToDeserializedProperty(string name) + { + if (_deserializeMap.TryGetValue(name, out PropertyMap map)) + { + return (map.To, map.IsCompressed); + } + return (name, false); + } + + public ContentNestedData Deserialize(string data) + { + // by default JsonConvert will deserialize our numeric values as Int64 + // which is bad, because they were Int32 in the database - take care + + var settings = new JsonSerializerSettings + { + Converters = new List { new ForceInt32Converter() }, + + }; + + return JsonConvert.DeserializeObject(data, settings); + } + + public string Serialize(ContentNestedData nestedData) + { + return JsonConvert.SerializeObject(nestedData); + } + } + + public class MappedPropertyDataContractResolver : DefaultContractResolver + { + private readonly IDictionary _serializeMap; + private readonly IDictionary _deserializeMap; + + + /// + /// Constructor + /// + /// Map for PropertData properties + /// + public MappedPropertyDataContractResolver(IDictionary serializeMap, IDictionary deserializeMap) + { + _serializeMap = serializeMap; + _deserializeMap = deserializeMap; + } + + public (string mappedName, bool isCompressed) ToSerializedProperty(string name) + { + if (_serializeMap.TryGetValue(name, out PropertyMap map)) + { + return (map.To, map.IsCompressed); + } + return (name, false); + } + public (string mappedName, bool isCompressed) ToDeserializedProperty(string name) + { + if (_deserializeMap.TryGetValue(name, out PropertyMap map)) + { + return (map.To, map.IsCompressed); + } + return (name, false); + } + + private readonly Type _type = typeof(PropertyData); + protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) + { + var property = base.CreateProperty(member, memberSerialization); + if (property.DeclaringType == _type) + { + if (property.PropertyName.Equals("LongPropertyName", StringComparison.OrdinalIgnoreCase)) + { + property.PropertyName = "Short"; + } + } + return property; + } + protected override string ResolvePropertyName(string propertyName) + { + return base.ResolvePropertyName(propertyName); + } + protected override JsonDictionaryContract CreateDictionaryContract(Type objectType) + { + JsonDictionaryContract contract = base.CreateDictionaryContract(objectType); + + contract.DictionaryKeyResolver = propertyName => propertyName; + + return contract; + } + } + + public class MappedNamingStrategy : NamingStrategy + { + public MappedNamingStrategy() + { + ProcessDictionaryKeys = true; + } + public override string GetDictionaryKey(string key) + { + return key; + } + + protected override string ResolvePropertyName(string name) + { + return name; + } + } + + + public class PropertyMap + { + /// + /// PropertyName + /// + public string To { get; set; } + /// + /// Whether the property is compressed + /// + public bool IsCompressed { get; set; } + } +} diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/PropertyData.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/PropertyData.cs index 4abcbc7e6f..cf7ab95360 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/PropertyData.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/PropertyData.cs @@ -4,7 +4,7 @@ using Newtonsoft.Json; namespace Umbraco.Web.PublishedCache.NuCache.DataSource { - internal class PropertyData + public class PropertyData { private string _culture; private string _segment; diff --git a/src/Umbraco.Web/PublishedCache/NuCache/NuCacheComposer.cs b/src/Umbraco.Web/PublishedCache/NuCache/NuCacheComposer.cs index f748fd555c..f67256bb6b 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/NuCacheComposer.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/NuCacheComposer.cs @@ -10,6 +10,9 @@ namespace Umbraco.Web.PublishedCache.NuCache { base.Compose(composition); + // register the NuCache NestedContentData serializer + composition.Register(); + // register the NuCache database data source composition.Register(); diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs index a39e26e2b1..b14deb7959 100755 --- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs @@ -48,6 +48,7 @@ namespace Umbraco.Web.PublishedCache.NuCache private readonly IPublishedModelFactory _publishedModelFactory; private readonly IDefaultCultureAccessor _defaultCultureAccessor; private readonly UrlSegmentProviderCollection _urlSegmentProviders; + private readonly IContentNestedDataSerializer _contentNestedDataSerializer; // volatile because we read it with no lock private volatile bool _isReady; @@ -81,7 +82,7 @@ namespace Umbraco.Web.PublishedCache.NuCache IDataSource dataSource, IGlobalSettings globalSettings, IEntityXmlSerializer entitySerializer, IPublishedModelFactory publishedModelFactory, - UrlSegmentProviderCollection urlSegmentProviders) + UrlSegmentProviderCollection urlSegmentProviders, IContentNestedDataSerializer contentNestedDataSerializer) : base(publishedSnapshotAccessor, variationContextAccessor) { //if (Interlocked.Increment(ref _singletonCheck) > 1) @@ -98,6 +99,7 @@ namespace Umbraco.Web.PublishedCache.NuCache _defaultCultureAccessor = defaultCultureAccessor; _globalSettings = globalSettings; _urlSegmentProviders = urlSegmentProviders; + _contentNestedDataSerializer = contentNestedDataSerializer; // we need an Xml serializer here so that the member cache can support XPath, // for members this is done by navigating the serialized-to-xml member @@ -1457,7 +1459,7 @@ namespace Umbraco.Web.PublishedCache.NuCache // note that numeric values (which are Int32) are serialized without their // type (eg "value":1234) and JsonConvert by default deserializes them as Int64 - Data = JsonConvert.SerializeObject(nestedData) + Data = _contentNestedDataSerializer.Serialize(nestedData) }; //Core.Composing.Current.Logger.Debug(dto.Data); diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index b1cbff0fef..01f81cfc83 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -245,6 +245,8 @@ + + From 7ad019c18a38265187bd1bb0ac9f745ce3f8d440 Mon Sep 17 00:00:00 2001 From: nzdev <834725+nzdev@users.noreply.github.com> Date: Wed, 1 Jul 2020 17:49:34 +1200 Subject: [PATCH 2/2] remove example nested content serializer as it is not production ready. --- ...opertiesJsonContentNestedDataSerializer.cs | 157 ------------------ 1 file changed, 157 deletions(-) delete mode 100644 src/Umbraco.Web/PublishedCache/NuCache/DataSource/MappedPropertiesJsonContentNestedDataSerializer.cs diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/MappedPropertiesJsonContentNestedDataSerializer.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/MappedPropertiesJsonContentNestedDataSerializer.cs deleted file mode 100644 index 4919404e11..0000000000 --- a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/MappedPropertiesJsonContentNestedDataSerializer.cs +++ /dev/null @@ -1,157 +0,0 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; -using Umbraco.Core.Serialization; - -namespace Umbraco.Web.PublishedCache.NuCache.DataSource -{ - public class MappedPropertiesJsonContentNestedDataSerializer : IContentNestedDataSerializer - { - private readonly IDictionary _serializeMap; - private readonly IDictionary _deserializeMap; - - - /// - /// Constructor - /// - /// Map for PropertData properties - /// - public MappedPropertiesJsonContentNestedDataSerializer(IDictionary serializeMap, IDictionary deserializeMap) - { - _serializeMap = serializeMap; - _deserializeMap = deserializeMap; - } - - public (string mappedName, bool isCompressed) ToSerializedProperty(string name) - { - if(_serializeMap.TryGetValue(name,out PropertyMap map)) - { - return (map.To,map.IsCompressed); - } - return (name,false); - } - public (string mappedName, bool isCompressed) ToDeserializedProperty(string name) - { - if (_deserializeMap.TryGetValue(name, out PropertyMap map)) - { - return (map.To, map.IsCompressed); - } - return (name, false); - } - - public ContentNestedData Deserialize(string data) - { - // by default JsonConvert will deserialize our numeric values as Int64 - // which is bad, because they were Int32 in the database - take care - - var settings = new JsonSerializerSettings - { - Converters = new List { new ForceInt32Converter() }, - - }; - - return JsonConvert.DeserializeObject(data, settings); - } - - public string Serialize(ContentNestedData nestedData) - { - return JsonConvert.SerializeObject(nestedData); - } - } - - public class MappedPropertyDataContractResolver : DefaultContractResolver - { - private readonly IDictionary _serializeMap; - private readonly IDictionary _deserializeMap; - - - /// - /// Constructor - /// - /// Map for PropertData properties - /// - public MappedPropertyDataContractResolver(IDictionary serializeMap, IDictionary deserializeMap) - { - _serializeMap = serializeMap; - _deserializeMap = deserializeMap; - } - - public (string mappedName, bool isCompressed) ToSerializedProperty(string name) - { - if (_serializeMap.TryGetValue(name, out PropertyMap map)) - { - return (map.To, map.IsCompressed); - } - return (name, false); - } - public (string mappedName, bool isCompressed) ToDeserializedProperty(string name) - { - if (_deserializeMap.TryGetValue(name, out PropertyMap map)) - { - return (map.To, map.IsCompressed); - } - return (name, false); - } - - private readonly Type _type = typeof(PropertyData); - protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) - { - var property = base.CreateProperty(member, memberSerialization); - if (property.DeclaringType == _type) - { - if (property.PropertyName.Equals("LongPropertyName", StringComparison.OrdinalIgnoreCase)) - { - property.PropertyName = "Short"; - } - } - return property; - } - protected override string ResolvePropertyName(string propertyName) - { - return base.ResolvePropertyName(propertyName); - } - protected override JsonDictionaryContract CreateDictionaryContract(Type objectType) - { - JsonDictionaryContract contract = base.CreateDictionaryContract(objectType); - - contract.DictionaryKeyResolver = propertyName => propertyName; - - return contract; - } - } - - public class MappedNamingStrategy : NamingStrategy - { - public MappedNamingStrategy() - { - ProcessDictionaryKeys = true; - } - public override string GetDictionaryKey(string key) - { - return key; - } - - protected override string ResolvePropertyName(string name) - { - return name; - } - } - - - public class PropertyMap - { - /// - /// PropertyName - /// - public string To { get; set; } - /// - /// Whether the property is compressed - /// - public bool IsCompressed { get; set; } - } -}