我有一个班级员工,经理属性本身是类型员工
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Employee Manager { get; set; }
public IList<string> Roles { get; set; }
}
我想为员工类型创建一个自定义的jsonconverter。
public class TestJsonConverter : JsonConverter
{
public TestJsonConverter()
{
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
JToken t = JToken.FromObject(value);
if (t.Type != JTokenType.Object)
{
t.WriteTo(writer);
}
else
{
JObject o = (JObject)t;
IList<string> propertyNames = o.Properties().Select(p => p.Name).ToList();
o.AddFirst(new JProperty("Keys", new JArray(propertyNames)));
o.WriteTo(writer);
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
}
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(Employee));
}
public override bool CanRead
{
get { return false; }
}
}
违规者是
class ContractResolver : DefaultContractResolver
{
protected override JsonObjectContract CreateObjectContract(Type objectType)
{
JsonObjectContract contract = base.CreateObjectContract(objectType);
if (objectType == typeof(Employee))
{
contract.Converter = new TestJsonConverter();
}
return contract;
}
}
当我尝试序列化员工对象时,自定义JSONCONVERTER仅适用于顶级员工对象,而不是嵌套管理器属性(也是员工类型的嵌套管理属性:
)JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new ContractResolver();
string json = JsonConvert.SerializeObject(employee, Formatting.Indented, settings);
我认为您遇到了相同的问题自定义JSONCONVERTER WERTINJSON不会更改子专业的序列化:
您的转换器没有应用于子对象的原因是因为jtoken.fromobject()在内部使用序列化器的新实例,该实例不知道您的转换器。
所提供的解决方案应适应您的案件。
,因此JsonConverter
从根节点开始运行一次。您需要浏览此JSON对象树并自行更新。
不确定这是您打算实现的目标,但我自己尝试了,您可以决定这是否适合您。
public class TestJsonConverter : JsonConverter
{
public TestJsonConverter()
{
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
JToken t = JToken.FromObject(value);
if (t.Type != JTokenType.Object)
{
t.WriteTo(writer);
}
else
{
JObject root = (JObject)t;
var stack = new Stack<JObject>();
stack.Push(root);
while (stack.Any())
{
var current = stack.Pop();
var propertyNames = current.Properties().Select(p => p.Name).ToArray();
current.AddFirst(new JProperty("Keys", new JArray(propertyNames)));
var nestedObjects = current.Properties().Where(p => p.Value.Type == JTokenType.Object).ToArray();
foreach (var nestedObj in nestedObjects)
{
stack.Push((JObject)nestedObj.Value);
}
}
root.WriteTo(writer);
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
}
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(Employee));
}
public override bool CanRead
{
get { return false; }
}
}