Serialize only interface properties to JSON with Json.net

前端 未结 9 1948
孤街浪徒
孤街浪徒 2020-12-08 19:50

With a simple class/interface like this

public interface IThing
{
    string Name { get; set; }
}

public class Thing : IThing
{
    public int Id { get; se         


        
相关标签:
9条回答
  • 2020-12-08 20:25

    I'd like to share what we ended up doing when confronted with this task. Given the OP's interface and class...

    public interface IThing
    {
        string Name { get; set; }
    }
    
    public class Thing : IThing
    {
       public int Id { get; set; }
       public string Name { get; set; }
    }
    

    ...we created a class that is the direct implementation of the interface...

    public class DirectThing : IThing
    {
       public string Name { get; set; }
    }
    

    Then simply serialized our Thing instance, deserialized it as a DirectThing, then Serialized it as a DirectThing:

    var thing = new Thing();
    JsonConvert.SerializeObject(
        JsonConvert.DeserializeObject<DirectThing>(JsonConvert.SerializeObject(thing)));
    

    This approach can work with a long interface inheritance chain...you just need to make a direct class (DirectThing in this example) at the level of interest. No need to worry about reflection or attributes.

    From a maintenance perspective, the DirectThing class is easy to maintain if you add members to IThing because the compiler will give errors if you haven't also put them in DirectThing. However, if you remove a member X from IThing and put it in Thing instead, then you'll have to remember to remove it from DirectThing or else X would be in the end result.

    From a performance perspective there are three (de)serialization operations happening here instead of one, so depending on your situation you might like to evaluate the performance difference of reflector/attribute-based solutions versus this solution. In my case I was just doing this on a small scale, so I wasn't concerned about potential losses of some micro/milliseconds.

    Hope that helps someone!

    0 讨论(0)
  • 2020-12-08 20:26

    in addition to the answer given by @monrow you can use the default [DataContract] and [DataMember] have a look at this

    http://james.newtonking.com/archive/2009/10/23/efficient-json-with-json-net-reducing-serialized-json-size.aspx

    0 讨论(0)
  • 2020-12-08 20:29

    The method I use,

    public class InterfaceContractResolver : DefaultContractResolver
    {
        private readonly Type _InterfaceType;
        public InterfaceContractResolver (Type InterfaceType)
        {
            _InterfaceType = InterfaceType;
        }
    
        protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
        {
            //IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
            IList<JsonProperty> properties = base.CreateProperties(_InterfaceType, memberSerialization);
            return properties;
        }
    }
    
    // To serialize do this:
    var settings = new JsonSerializerSettings() {
         ContractResolver = new InterfaceContractResolver (typeof(IThing))
    });
    string json = JsonConvert.SerializeObject(theObjToSerialize, settings);
    
    0 讨论(0)
提交回复
热议问题