Json.net how to serialize object as value

前端 未结 6 1424
滥情空心
滥情空心 2020-12-15 19:06

I\'ve pored through the docs, StackOverflow, etc., can\'t seem to find this...

What I want to do is serialize/deserialize a simple value-type of object as a value, n

6条回答
  •  [愿得一人]
    2020-12-15 19:07

    This is a answer to Customise NewtonSoft.Json for Value Object serialisation, in regards to value objects in DDD. But that question is marked as duplicate to this one, which i don't think is completely true.

    I borrowed the code for the ValueObjectConverter from https://github.com/eventflow/EventFlow, I have only done minor changes.

    using System;
    using System.Collections.Concurrent;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using FluentAssertions;
    using Newtonsoft.Json;
    using Xunit;
    
    namespace Serialization
    {
        public class ValueObjectSerializationTests
        {
            class SomeClass
            {
                public IPAddress IPAddress { get; set; }
            }
    
            [Fact]
            public void FactMethodName()
            {
                var given = new SomeClass
                {
                    IPAddress = new IPAddress("192.168.1.2")
                };
    
                var jsonSerializerSettings = new JsonSerializerSettings()
                {
                    Converters = new List
                                 {
                                    new ValueObjectConverter()
                                 }
                };
                var json = JsonConvert.SerializeObject(given, jsonSerializerSettings);
    
                var result = JsonConvert.DeserializeObject(json, jsonSerializerSettings);
    
                var expected = new SomeClass
                {
                    IPAddress = new IPAddress("192.168.1.2")
                };
    
                json.Should().Be("{\"IPAddress\":\"192.168.1.2\"}");
                expected.ShouldBeEquivalentTo(result);
            }
        }
    
        public class IPAddress:IValueObject
        {
            public IPAddress(string value)
            {
                Value = value;
            }
    
            public object GetValue()
            {
                return Value;
            }
    
            public string Value { get; private set; }
        }
    
        public interface IValueObject
        {
            object GetValue();
        }
    
        public class ValueObjectConverter : JsonConverter
        {
            private static readonly ConcurrentDictionary ConstructorArgumenTypes = new ConcurrentDictionary();
    
            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                if (!(value is IValueObject valueObject))
                {
                    return;
                }
    
                serializer.Serialize(writer, valueObject.GetValue());
            }
    
            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                var parameterType = ConstructorArgumenTypes.GetOrAdd(
                    objectType,
                    t =>
                    {
                        var constructorInfo = objectType.GetConstructors(BindingFlags.Public | BindingFlags.Instance).First();
                        var parameterInfo = constructorInfo.GetParameters().Single();
                        return parameterInfo.ParameterType;
                    });
    
                var value = serializer.Deserialize(reader, parameterType);
                return Activator.CreateInstance(objectType, new[] { value });
            }
    
            public override bool CanConvert(Type objectType)
            {
                return typeof(IValueObject).IsAssignableFrom(objectType);
            }
        }
    }
    

提交回复
热议问题