Din*_*ale 31 .net c# system.net json.net
我试图用Json.Net序列化IPEndpoint对象,我收到以下错误:
从'System.Net.IPAddress'上的'ScopeId'获取值时出错.
导致错误的原因是我只使用端点中IPAddress对象的IPV4属性.当Json解析器尝试解析IPv6部分时,它会访问ScopeID属性,该属性会抛出套接字异常"对于引用的对象类型,不支持尝试的操作"(null将足以支持microsoft!)
我想知道除了撕掉一切并将地址信息编码为字符串之外是否还有其他解决方法?在某些时候,我确实想支持IPV6.如果IPAddress系列设置为Internetwork而不是InternetworkIPV6,是否有任何可以在Json.NET中完成忽略错误或只是不尝试序列化ScopeID?
谢谢,
Dinsdale
Bri*_*ers 62
该IPAddress班是不是系列化非常友好,如您所见.SocketException如果您尝试访问ScopeIDIPv4地址的字段,它不仅会抛出一个,但如果您尝试Address直接访问该字段以获取IPv6地址,它也会抛出.
要解决异常,您需要自定义JsonConverter.转换器允许您准确告诉Json.Net如何序列化和/或反序列化特定类型的对象.对于一个IPAddress,似乎获得满足每个人的数据的最简单方法就是将其转换为字符串表示并返回.我们可以在转换器中做到这一点.我是这样写的:
class IPAddressConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(IPAddress));
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(value.ToString());
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return IPAddress.Parse((string)reader.Value);
}
}
Run Code Online (Sandbox Code Playgroud)
这些事情都很简单.但是,这不是故事的结局.如果你需要和你一起往返IPEndPoint,那么你也需要一个转换器.为什么?因为IPEndPoint不包含默认构造函数,所以Json.Net将不知道如何实例化它.幸运的是,这个转换器也不难写:
class IPEndPointConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(IPEndPoint));
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
IPEndPoint ep = (IPEndPoint)value;
JObject jo = new JObject();
jo.Add("Address", JToken.FromObject(ep.Address, serializer));
jo.Add("Port", ep.Port);
jo.WriteTo(writer);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
IPAddress address = jo["Address"].ToObject<IPAddress>(serializer);
int port = (int)jo["Port"];
return new IPEndPoint(address, port);
}
}
Run Code Online (Sandbox Code Playgroud)
那么,既然我们有转换器,我们如何使用它们?这是一个演示的简单示例程序.它首先创建几个端点,使用自定义转换器将它们序列化为JSON,然后使用相同的转换器立即将JSON重新反序列化为端点.
public class Program
{
static void Main(string[] args)
{
var endpoints = new IPEndPoint[]
{
new IPEndPoint(IPAddress.Parse("8.8.4.4"), 53),
new IPEndPoint(IPAddress.Parse("2001:db8::ff00:42:8329"), 81)
};
var settings = new JsonSerializerSettings();
settings.Converters.Add(new IPAddressConverter());
settings.Converters.Add(new IPEndPointConverter());
settings.Formatting = Formatting.Indented;
string json = JsonConvert.SerializeObject(endpoints, settings);
Console.WriteLine(json);
var endpoints2 = JsonConvert.DeserializeObject<IPEndPoint[]>(json, settings);
foreach (IPEndPoint ep in endpoints2)
{
Console.WriteLine();
Console.WriteLine("AddressFamily: " + ep.AddressFamily);
Console.WriteLine("Address: " + ep.Address);
Console.WriteLine("Port: " + ep.Port);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是输出:
[
{
"Address": "8.8.4.4",
"Port": 53
},
{
"Address": "2001:db8::ff00:42:8329",
"Port": 81
}
]
AddressFamily: InterNetwork
Address: 8.8.4.4
Port: 53
AddressFamily: InterNetworkV6
Address: 2001:db8::ff00:42:8329
Port: 81
Run Code Online (Sandbox Code Playgroud)
小提琴:https://dotnetfiddle.net/tK7NKY
| 归档时间: |
|
| 查看次数: |
12871 次 |
| 最近记录: |