如何在 NewtonSoft.Json 中配置 returns json 而不是字符串的自定义转换器?
How do I configure a custom converter that returns json, instead of a string, in NewtonSoft.Json?
我有一个包含 NetTopologySuite 多边形的简单模型:
public class MyModel
{
[Newtonsoft.Json.JsonConverter(typeof(MyPolygonConverter))]
public NetTopologySuite.Geometries.Polygon poly { get; set; }
}
我已经构建了一个自定义转换器,使用 NetTopologySuite.IO.GeoJson:
public class MyPolygonConverter : JsonConverter<Polygon>
{
public override void WriteJson(JsonWriter writer, Polygon value, JsonSerializer serializer)
{
var geoJsonSerializer = NetTopologySuite.IO.GeoJsonSerializer.Create();
using var stringWriter = new StringWriter();
using var jsonWriter = new JsonTextWriter(stringWriter);
geoJsonSerializer.Serialize(jsonWriter, value);
var geoJson = stringWriter.ToString();
writer.WriteValue(geoJson);
}
...
}
然后我创建一个模型对象并将其序列化:
var model = new MyModel
{
poly = new Polygon(new LinearRing(new[]
{
new Coordinate(-100, 45),
new Coordinate(-98, 45),
new Coordinate(-99, 46),
new Coordinate(-100, 45),
}))
};
var geoJson = JsonConvert.SerializeObject(model, Formatting.None,
new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
NullValueHandling = NullValueHandling.Ignore
});
我得到的包含多边形作为转义的 GeoJson 字符串:
{
"poly" : "{\"type\":\"Polygon\",\"coordinates\":[[[-100.0,45.0],[-98.0,45.0],[-99.0,46.0],[-100.0,45.0]]]}"
}
我想要的是 json 中的多边形,在 json 对象中:
{
"poly" : {
"type" : "Polygon",
"coordinates" : [
[
[-100.0,45.0],
[-98.0,45.0],
[-99.0,46.0],
[-100.0,45.0]
]
]
}
}
我在想的是我根本不应该使用 JsonConverter,而是其他东西。
但是什么?
您可以使用 JsonWriter.WriteRawValue(string)
将原始 JSON 值直接写入 JSON 输出:
writer.WriteRawValue(geoJson);
也就是说,GeoJsonSerializer
is a subclass of Newtonsoft's own JsonSerializer
so you can just pass the incoming JsonWriter
in to its Serialize()
方法:
public override void WriteJson(JsonWriter writer, Polygon value, JsonSerializer serializer)
{
var geoJsonSerializer = NetTopologySuite.IO.GeoJsonSerializer.Create();
geoJsonSerializer.Serialize(writer, value);
}
演示 fiddle #1 here.
GeoJsonSerializer
和基础 class 的唯一区别是 NullValueHandling.Ignore
默认启用并且添加了几个转换器,所以你也可以只使用这个序列化程序来序列化 您的整个模型,从而无需将 [Newtonsoft.Json.JsonConverter(typeof(MyPolygonConverter))]
添加到您的模型:
var serializer = NetTopologySuite.IO.GeoJsonSerializer.CreateDefault(
new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
NullValueHandling = NullValueHandling.Ignore,
Formatting = Formatting.Indented, // Or none, if you prefer
});
var sb = new StringBuilder();
using (var sw = new StringWriter(sb))
using (var jsonWriter = new JsonTextWriter(sw))
serializer.Serialize(jsonWriter, model);
var geoJson = sb.ToString();
演示 fiddle #2 here.
我有一个包含 NetTopologySuite 多边形的简单模型:
public class MyModel
{
[Newtonsoft.Json.JsonConverter(typeof(MyPolygonConverter))]
public NetTopologySuite.Geometries.Polygon poly { get; set; }
}
我已经构建了一个自定义转换器,使用 NetTopologySuite.IO.GeoJson:
public class MyPolygonConverter : JsonConverter<Polygon>
{
public override void WriteJson(JsonWriter writer, Polygon value, JsonSerializer serializer)
{
var geoJsonSerializer = NetTopologySuite.IO.GeoJsonSerializer.Create();
using var stringWriter = new StringWriter();
using var jsonWriter = new JsonTextWriter(stringWriter);
geoJsonSerializer.Serialize(jsonWriter, value);
var geoJson = stringWriter.ToString();
writer.WriteValue(geoJson);
}
...
}
然后我创建一个模型对象并将其序列化:
var model = new MyModel
{
poly = new Polygon(new LinearRing(new[]
{
new Coordinate(-100, 45),
new Coordinate(-98, 45),
new Coordinate(-99, 46),
new Coordinate(-100, 45),
}))
};
var geoJson = JsonConvert.SerializeObject(model, Formatting.None,
new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
NullValueHandling = NullValueHandling.Ignore
});
我得到的包含多边形作为转义的 GeoJson 字符串:
{
"poly" : "{\"type\":\"Polygon\",\"coordinates\":[[[-100.0,45.0],[-98.0,45.0],[-99.0,46.0],[-100.0,45.0]]]}"
}
我想要的是 json 中的多边形,在 json 对象中:
{
"poly" : {
"type" : "Polygon",
"coordinates" : [
[
[-100.0,45.0],
[-98.0,45.0],
[-99.0,46.0],
[-100.0,45.0]
]
]
}
}
我在想的是我根本不应该使用 JsonConverter,而是其他东西。
但是什么?
您可以使用 JsonWriter.WriteRawValue(string)
将原始 JSON 值直接写入 JSON 输出:
writer.WriteRawValue(geoJson);
也就是说,GeoJsonSerializer
is a subclass of Newtonsoft's own JsonSerializer
so you can just pass the incoming JsonWriter
in to its Serialize()
方法:
public override void WriteJson(JsonWriter writer, Polygon value, JsonSerializer serializer)
{
var geoJsonSerializer = NetTopologySuite.IO.GeoJsonSerializer.Create();
geoJsonSerializer.Serialize(writer, value);
}
演示 fiddle #1 here.
GeoJsonSerializer
和基础 class 的唯一区别是 NullValueHandling.Ignore
默认启用并且添加了几个转换器,所以你也可以只使用这个序列化程序来序列化 您的整个模型,从而无需将 [Newtonsoft.Json.JsonConverter(typeof(MyPolygonConverter))]
添加到您的模型:
var serializer = NetTopologySuite.IO.GeoJsonSerializer.CreateDefault(
new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
NullValueHandling = NullValueHandling.Ignore,
Formatting = Formatting.Indented, // Or none, if you prefer
});
var sb = new StringBuilder();
using (var sw = new StringWriter(sb))
using (var jsonWriter = new JsonTextWriter(sw))
serializer.Serialize(jsonWriter, model);
var geoJson = sb.ToString();
演示 fiddle #2 here.