如何使用Newtonsoft.Json将对象序列化为带有类型信息的json?

Ext*_*xta 29 c# serialization json.net

当我序列化某些类型的对象时,我希望在JSON中有一个类型名称的属性.我写了一个转换器:

public class TypeInfoConverter : JsonConverter {
    private readonly IEnumerable<Type> _types;

    public TypeInfoConverter(IEnumerable<Type> types) {
        Contract.Requires(types != null);

        _types = types;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
        var jObject = JObject.FromObject(value, serializer);
        jObject.AddFirst(new JProperty("Type", value.GetType().Name));
        jObject.WriteTo(writer);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
        return serializer.Deserialize(reader, objectType);
    }

    public override bool CanConvert(Type objectType) {
        return _types.Any(t => t.IsAssignableFrom(objectType));
    }
}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试序列化对象时,我在这里有一个无限递归: var jObject = JObject.FromObject(value, serializer);很明显,因为我使用了与该转换器配置的JsonSerializer相同的实例.

如何防止使用此转换器,但我想使用为此序列化器配置的其他转换器?

我要序列化的类型:

public interface ITaskResult {
}

public class UserHasRejectedOffer : ITaskResult {
    public string Message { get; set; }
}

public class UserHasFilledForm : ITaskResult {
    public string FormValue1 { get; set; }

    public string Formvalue2 { get; set; }
}

...
Run Code Online (Sandbox Code Playgroud)

Cal*_*ale 57

var jsonSerializerSettings = new JsonSerializerSettings() { 
    TypeNameHandling = TypeNameHandling.All
};
var json = JsonConvert.SerializeObject(instance, jsonSerializerSettings);
Run Code Online (Sandbox Code Playgroud)

http://james.newtonking.com/json/help/index.html?topic=html/SerializationSettings.htm

  • 非常简单的解决方案。有什么方法可以只输出没有命名空间和项目名称的类名? (2认同)

Ext*_*xta 11

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    var converters = serializer.Converters.Where(x => !(x is TypeInfoConverter)).ToArray();

    var jObject = JObject.FromObject(value);
    jObject.AddFirst(new JProperty("Type", value.GetType().Name));
    jObject.WriteTo(writer, converters);
}
Run Code Online (Sandbox Code Playgroud)

  • 这是比我的更好的解决方案.你实际上可以像你原来那样做`jObject.WriteTo(writer,converter)`而不是单独编写每个属性. (2认同)