Json.NET TypeNameHandling仅供阅读

时间:2017-06-22 11:11:05

标签: c# json.net

我使用以下JsonSerializerSettings

new JsonSerializerSettings {
    TypeNameHandling = TypeNameHandling.Objects
}
  

获取或设置序列化程序如何处理类型名称写入和读取。

我想知道是否有任何方法可以启用类型名称读取,但在写入期间禁用它。

我反序列化了一个抽象基类列表,所以我需要JSON上的$type个节点能够反序列化(使用自定义的SerializationBinder),但我不希望我的回复包括在内他们的类型和命名空间。

请注意,我指的是 ASP.NET Web API 上下文中的(de)序列化,我只能在Configuration.Formatters的JsonFormatter上设置全局级别的SerializerSettings或使用IControllerConfiguration在控制器级别上。这些设置始终用于读写。

2 个答案:

答案 0 :(得分:1)

由于只有特定DTO需要此TypeNameHandling,我才创建了自定义JsonConverter

public class CustomJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(MyDTO);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var customSerializer = new JsonSerializer {
            TypeNameHandling = TypeNameHandling.Objects, 
            Binder = new CustomSerializationBinder()
        };
        return customSerializer.Deserialize(reader, objectType);
    }
}

并在JsonFormatter上注册了

Configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new CustomJsonConverter());

答案 1 :(得分:0)

是否使用TypeNameHandling可以基于SerializeObject / DeserializeObject来定义。因此,当您不需要$type时,请不要使用这些设置:

var typedJson = @"{""$type"":""ConsoleApp2.Program+TestData, ConsoleApp2"",""TestField"":0}";
var testData = JsonConvert.DeserializeObject(typedJson, new JsonSerializerSettings {
    TypeNameHandling = TypeNameHandling.Objects
});
var json = JsonConvert.SerializeObject(testData);    // <----- Notice no settings here
Console.WriteLine(json);

// Outputs:
//     {"TestField":0}