IPAddress
sınıf, serileştirme çok kolay değil. Bir IPv4 adresi için ScopeID
alanına erişmeye çalışırsanız, yalnızca bir SocketException
atmakla kalmaz, aynı zamanda bir IPv6 adresi için doğrudan Address
alanına erişmeye çalışırsanız, bu özellik atılır.
Özel durumları aşmak için, özel bir JsonConverter
'a ihtiyacınız olacak. Bir dönüştürücü, Json.Net'e tam olarak, belirli bir nesne türünü seri hale getirme ve/veya serileştirilmesini nasıl istediğinizi söylemenizi sağlar. Bir IPAddress
için, herkese uygun verilerin basitçe onun dize temsili ve geri dönüşüme dönüştürülmesinin en kolay yolu görünüyor. Bunu dönüştürücüde yapabiliriz. İşte ben şöyle yazabilirim:
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);
}
}
Oldukça basit, bu şeyler gittikçe. Ama bu hikayenin sonu değil. IPEndPoint
ile gidiş-dönüş yapmanız gerekiyorsa, bunun için bir dönüştürücüye de ihtiyacınız olacaktır. Niye ya? IPEndPoint
, varsayılan bir kurucu içermediğinden, Json.Net bunu nasıl başlatacağını bilmeyecektir.
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);
}
}
Mademki artık dönüştürücüler var olduğunu, bunları nasıl kullanırım: Neyse ki, bu dönüştürücü ya yazmak zor değil mi? İşte gösteren basit bir örnek programdır. İlk önce birkaç bitiş noktası yaratır, bunları özel dönüştürücüler kullanarak JSON'a serer, ardından JSON'u aynı dönüştürücüleri kullanarak tekrar uç noktalara geri gönderir. İşte
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);
}
}
}
çıktısı:
[
{
"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
Fiddle: WriteJson` çok `JObject` kullanılarak basitleştirilmiş olabilir` arasında https://dotnetfiddle.net/tK7NKY
Kodu. – Athari
Parlak. Çok teşekkür ederim Brian! – Dinsdale
Sorun yok; yardım etmekten memnunum. –