如何使用包含“原始"字符串的字符串成员来序列化和反序列化类型. JSON,而不会在此过程中转义JSON [英] How can I serialize and deserialize a type with a string member that contains "raw" JSON, without escaping the JSON in the process

查看:81
本文介绍了如何使用包含“原始"字符串的字符串成员来序列化和反序列化类型. JSON,而不会在此过程中转义JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将JSON反序列化为Object,但我不想反序列化嵌套的JSON,嵌套的JSON嵌套应转换为JSON列表(请检查"我的预期输出"以了解清晰的主意). ..

I want to Deserialize JSON into Object but I don't want to Deserialize nested JSON, nested of nested JSON should convert into JSON list (Please check "My expected output" for clear idea) ...

//假设我有下面的JSON数据,在这里我为地址"实体嵌套了JSON

// Suppose I have below JSON data, Here I have nested JSON for "Address" entity

String jsonEmployees =
"{"Employees":
[{"EmpId":1, "EmpName":"ABC", "Address":[{"AddressId":1, "Address":"Something"},{"AddressId":2, "Address":"Anything"}]},
{"EmpId":2, "EmpName":"XYZ", "Address":[{"AddressId":1, "Address":"Something"},{"AddressId":2, "Address":"Anything"}]}]
}"

public class Employee
{
    public int EmpId { get; set; }
    public string EmpName { get; set; }
    // **Note** : I'm not using List<Address> data type for Address, instead of I want list of address in JSON string
    public string Address { get; set; }
}

public class RootObject
{
    public List<Employee> Employees { get; set; }
}

var Employees = JsonConvert.DeserializeObject<RootObject>(jsonEmployees);

//我的预期输出

Employees[0].EmpId = 1;
Employees[0].EmpName = "ABC";
Employees[0].Address = "[{"AddressId":1, "Address":"Something"},{"AddressId":2, "Address":"Anything"}]";

Employees[1].EmpId = 2;
Employees[1].EmpName = "XYZ";
Employees[1].Address = "[{"AddressId":1, "Address":"Something"},{"AddressId":2, "Address":"Anything"}]";

请向我建议解决此问题的最佳方法...

Please suggest me the best way to solve this issue ...

推荐答案

您的问题是,如何使用包含原始" JSON的string成员对类型进行序列化和反序列化,而又不转义JSON这个过程?

Your question is, How can I serialize and deserialize a type with a string member that contains "raw" JSON, without escaping the JSON in the process?

这可以通过自定义JsonConverter 完成并使用 JsonWriter.WriteRawValue()

This can be done via a custom JsonConverter that reads and writes raw JSON using JsonWriter.WriteRawValue() and JRaw.Create():

public class RawConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var raw = JRaw.Create(reader);
        return raw.ToString();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var s = (string)value;
        writer.WriteRawValue(s);
    }
}

然后按如下所示将其应用于您的类型:

Then apply it to your type as follows:

public class Employee
{
    public int EmpId { get; set; }
    public string EmpName { get; set; }
    // **Note** : I'm not using List<Address> data type for Address, instead of I want list of address in JSON string
    [JsonConverter(typeof(RawConverter))]
    public string Address { get; set; }
}

public class RootObject
{
    public List<Employee> Employees { get; set; }
}

示例小提琴.

请注意,原始JSON字符串必须代表有效的JSON.如果不是,则创建的JSON将不可读.如果要保证JSON文字有效,则可以在内部将JSON保持为已解析状态:

Note that the raw JSON string must represent valid JSON. If it does not, then the JSON created will be unreadable. If you want to guarantee that the JSON literal is valid, you can keep the JSON in a parsed state internally:

public class Employee
{
    public int EmpId { get; set; }
    public string EmpName { get; set; }

    [JsonProperty("Address")]
    JToken AddressToken { get; set; }

    [JsonIgnore]
    public string Address
    {
        get
        {
            if (AddressToken == null)
                return null;
            return AddressToken.ToString(Formatting.Indented); // Or Formatting.None if you prefer
        }
        set
        {
            if (value == null)
                AddressToken = null;
            else
                // Throw an exception if value is not valid JSON.
                AddressToken = JToken.Parse(value);
        }
    }
}

此实现不需要转换器.

这篇关于如何使用包含“原始"字符串的字符串成员来序列化和反序列化类型. JSON,而不会在此过程中转义JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆