[英]Serialize only simple types using Json.Net
I am not sure why anybody has not asked about this question yet but I am trying to serialize only simple types of a given object using IContractResolver
interface. 我不知道为什么有人还没有问过这个问题,但我试图使用
IContractResolver
接口仅序列化给定对象的简单类型。 I don't really want to mark each property using ShouldSerialize
method or JsonDataAttribute
or anything like this. 我真的不想使用
ShouldSerialize
方法或JsonDataAttribute
或类似的东西来标记每个属性。
What I have done so far shown as following on LinqPad 到目前为止我所做的事情在LinqPad上显示如下
Some sample classes to serialize 一些要序列化的示例类
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;}
}
An extension method to serialize all the objects 一种序列化所有对象的扩展方法
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);
}
}
My Custom Contract Resolver Class 我的自定义合同解析器类
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;
}
}
and Main method: 和主要方法:
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();
}
I only want to serialize sample types such as int
, double
, string
, decimal
, bool
etc. but not arrays, collections, custom objects etc. and it will only navigate the first level, not 2nd or more levels down. 我只想序列化样本类型,如
int
, double
, string
, decimal
, bool
等,但不是数组,集合,自定义对象等。它只会导航到第一级,而不是第二级或更多级。 I really wonder why there is not any simple method which does this in Json.Net. 我真的很想知道为什么在Json.Net中没有任何简单的方法可以做到这一点。
This is the output when I run this code: (an empty json) 这是我运行此代码时的输出:(一个空的json)
{ }
{}
I've realized one thing when I run this code, the first member
parameter passed into the CreateProperty
method is the main object itself which in this case is Customer
instance. 我在运行此代码时已经意识到一件事,传递给
CreateProperty
方法的第一个member
参数是主对象本身,在本例中是Customer
实例。 But since this will work for all sort of types I just don't want to say instance.GetType() == typeof(Customer)
or something like this in the method. 但是因为这适用于所有类型的我只是不想说
instance.GetType() == typeof(Customer)
或类似的方法。 The expected output in this case is only CustomerId
in this case. 在这种情况下,此情况下的预期输出仅为
CustomerId
。
Do you know any graceful way to handle my problem? 你知道任何优雅的方式来处理我的问题吗?
By changing the method below I got the result: {"CustomerId":1}. 通过更改下面的方法,我得到了结果:{“CustomerId”:1}。 Is this what you were looking for?
这是你在找什么?
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;
}
}
Instead of overriding CreateProperty
method, I am overriding GetSerializableObjects
method as it gives all the possible members I will get: 我没有覆盖
CreateProperty
方法,而是覆盖了GetSerializableObjects
方法,因为它提供了我将获得的所有可能的成员:
public class MyContractResolver: DefaultContractResolver
{
protected override List<MemberInfo> GetSerializableMembers(Type objectType)
{
var members = base.GetSerializableMembers(objectType);
var filteredMembers = new List<MemberInfo>();
members.ForEach(m=>{
if(m.MemberType == MemberTypes.Property)
{
PropertyInfo info = (PropertyInfo) m;
var type = info.PropertyType;
if(type.IsPrimitive || type == typeof(string) || type == typeof(decimal))
{
filteredMembers.Add(m);
}
}
});
return filteredMembers;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.