使用Json.Net仅序列化简单类型

Tar*_*rik 9 .net c# json json.net

我不知道为什么有人还没有问过这个问题但是我试图使用IContractResolver接口仅序列化给定对象的简单类型.我真的不想使用ShouldSerialize方法或JsonDataAttribute类似的东西标记每个属性.

到目前为止我所做的事情在LinqPad上显示如下

一些要序列化的示例类

class Customer
{
    public List<Order> Orders {get;set;}
    public int CustomerId {get;set;}
    public string[] Addresses {get;set;}
}

class Order
{
    public int OrderId{get;set;}
    public string Name {get;set;}
    public int Amount {get;set;}
    public Order PreviousOrder {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

一种序列化所有对象的扩展方法

static class ExtensionMethods
{
    public static string JsonSerialize (this object obj)
    {
        var settings = new JsonSerializerSettings();
        settings.ContractResolver = new MyContractResolver();
        settings.DefaultValueHandling = DefaultValueHandling.Ignore;
        settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
        return JsonConvert.SerializeObject(obj,settings);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的自定义合同解析器类

public class MyContractResolver: DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member,memberSerialization);
        property.ShouldSerialize = instance => instance.GetType().IsPrimitive || instance.GetType() == typeof(string) || instance.GetType() == typeof(decimal);
        return property;
    }
}
Run Code Online (Sandbox Code Playgroud)

和主要方法:

void Main()
{
    var customer = new Customer
                {
                    Orders = ProduceSomeOrders(),
                    Addresses = new string[] {"9450 S. Small Street Dr.","9521 Flintstone Dr. S"},
                    CustomerId = 1
                };

    var jsonOrder = customer.JsonSerialize();
    jsonOrder.Dump();
}
Run Code Online (Sandbox Code Playgroud)

我只是想序列样本类型,例如int,double,string,decimal,bool等,但不是数组,集合,自定义对象等,它只会导航的第一级,第二个没有或多个级别向下.我真的很想知道为什么在Json.Net中没有任何简单的方法可以做到这一点.

这是我运行此代码时的输出:(一个空的json)

{}

我在运行此代码时已经意识到一件事,member传递给CreateProperty方法的第一个参数是主对象本身,在本例中是Customer实例.但是因为这适用于所有类型的我只是不想instance.GetType() == typeof(Customer)在方法中说或类似的东西.在这种情况下,预期输出仅CustomerId在这种情况下.

你知道任何优雅的方式来处理我的问题吗?

Tal*_*hay 5

通过更改下面的方法,我得到了结果:{"CustomerId":1}.这是你在找什么?

public class MyContractResolver:DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
    var property = base.CreateProperty(member,memberSerialization);

    var propertyType = property.PropertyType;
    if(propertyType == typeof(int) 
        || propertyType == typeof(string)){
        property.ShouldSerialize = instance => true;
    }
    else
    {
        property.ShouldSerialize = instance => false;
    }
    return property;
}
}
Run Code Online (Sandbox Code Playgroud)