Json.net如何将对象序列化为值

and*_*cus 18 c# json.net

我通过文档,StackOverflow等仔细研究,似乎无法找到这个......

我想要做的是将一个简单的值类型的对象序列化/反序列化为值,而不是对象,如下所示:

public class IPAddress
{
    byte[] bytes;

    public override string ToString() {... etc.
}

public class SomeOuterObject
{
    string stringValue;
    IPAddress ipValue;
}

IPAddress ip = new IPAddress("192.168.1.2");
var obj = new SomeOuterObject() {stringValue = "Some String", ipValue = ip};
string json = JsonConverter.SerializeObject(obj);
Run Code Online (Sandbox Code Playgroud)

我想要的是让json像这样序列化:

// json = {"someString":"Some String","ipValue":"192.168.1.2"} <- value serialized as value, not subobject
Run Code Online (Sandbox Code Playgroud)

不是ip成为嵌套对象的地方,例如:

// json = {"someString":"Some String","ipValue":{"value":"192.168.1.2"}}
Run Code Online (Sandbox Code Playgroud)

有谁知道如何做到这一点?谢谢!(PS我在大型毛茸茸的遗留.NET代码库上使用Json序列化,因此我无法真正更改任何现有类型,但我可以对它们进行扩充/因子/装饰以促进Json序列化.)

Bri*_*ers 23

您可以使用自定义处理此JsonConverterIPAddress类.以下是您需要的代码:

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return new IPAddress(JToken.Load(reader).ToString());
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        JToken.FromObject(value.ToString()).WriteTo(writer);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,[JsonConverter]向您的IPAddress班级添加一个属性,您就可以开始了:

[JsonConverter(typeof(IPAddressConverter))]
public class IPAddress
{
    byte[] bytes;

    public IPAddress(string address)
    {
        bytes = address.Split('.').Select(s => byte.Parse(s)).ToArray();
    }

    public override string ToString() 
    { 
        return string.Join(".", bytes.Select(b => b.ToString()).ToArray()); 
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个有效的演示:

class Program
{
    static void Main(string[] args)
    {
        IPAddress ip = new IPAddress("192.168.1.2");
        var obj = new SomeOuterObject() { stringValue = "Some String", ipValue = ip };
        string json = JsonConvert.SerializeObject(obj);
        Console.WriteLine(json);
    }
}

public class SomeOuterObject
{
    public string stringValue { get; set; }
    public IPAddress ipValue { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

输出:

{"stringValue":"Some String","ipValue":"192.168.1.2"}
Run Code Online (Sandbox Code Playgroud)


1' *_* -- 1

public class IPAddress
{
    byte[] bytes;

    public override string ToString() {... etc.
}

IPAddress ip = new IPAddress("192.168.1.2");
var obj = new () {ipValue = ip.ToString()};
string json = JsonConverter.SerializeObject(obj);
Run Code Online (Sandbox Code Playgroud)

您正在序列化整个 IP 地址实例。也许只是尝试将地址序列化为字符串。(这假定您已经实现了 ToString 方法。)