【问题标题】:partial serialization of json string: take only top level with JSON.NETjson 字符串的部分序列化:仅采用 JSON.NET 的顶层
【发布时间】:2014-06-12 23:15:38
【问题描述】:

请为我澄清一些困惑:我有一个 JSON 字符串,我试图将其插入对象中,但我只想获取顶层,并将下面的所有内容视为 blob 或字符串。像这样的。

这是我的模型:

public class InputJson
{
    [JsonProperty(PropertyName = "signals")]
    public string signals{ get; set; }
    [JsonProperty(PropertyName = "options")]
    public string options { get; set; }
    [JsonProperty(PropertyName = "fields")]
    public string fields{ get; set; }
    [JsonProperty(PropertyName = "lapse")]
    public string lapse{ get; set; }
}

我正在尝试像这样反序列化 JSON 字符串(见下文):

InputJson a = JsonConvert.DeserializeObject<InputJson>(body);

我希望a.signals 会返回一个字符串,其中包含“信号”下方和“选项”之前的所有内容,但它失败了,因为它试图继续前进并序列化它下面的所有内容。我得到一个JsonReaderException

读取字符串时出错。意外令牌:StartArray。路径“信号”,第 1 行,位置 12。

我尝试使用JsonSerializerSettings(例如将 maxDepth 设置为 1),但没有任何帮助。有人吗?

我的 JSON 字符串:

{
    "signals":
    [
        {
            "name":"1",
            "att1":"44",
            "att2":"0",
            "att3":"18",
            "size":10,
            "points":[-79,-29,-9,-23,27,-110,-39,-22,-32,-2]
        },
        {
            "name":"2",
            "att1":"46",
            "att2":"0",
            "att3":"12",
            "size":10,
            "points":[36,37,37,35,38,41,41,45,39,41]
        }
    ],
    "options":"opt1 opt2",
    "fields":"myfields",
    "lapse":"somelapse"
}

【问题讨论】:

    标签: c# json serialization json.net


    【解决方案1】:

    正如您正确推测的那样,您收到此错误是因为您的字段是字符串并且反序列化程序找到了一个数组。它不能将数组分配给字符串。

    您可以通过对您希望被视为“blob”的字段使用自定义JsonConverter 来解决此问题,我假设您的意思是您只需要原始 JSON 字符串。

    这是转换器所需的代码:

    class BlobJsonConverter: JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return (objectType == typeof(string));
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JToken token = JToken.Load(reader);
            return token.ToString(Formatting.None);
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
    

    然后,在您的模型中,使用 [JsonConverter] 属性装饰那些您希望被视为“blob”的字符串属性,如下所示:

    public class InputJson
    {
        [JsonProperty(PropertyName = "signals")]
        [JsonConverter(typeof(BlobJsonConverter))]
        public string signals { get; set; }
    
        [JsonProperty(PropertyName = "options")]
        public string options { get; set; }
    
        [JsonProperty(PropertyName = "fields")]
        public string fields { get; set; }
    
        [JsonProperty(PropertyName = "lapse")]
        public string lapse { get; set; }
    }
    

    现在,当您反序列化时,signals 将在“信号”下方包含原始 JSON,而不是给出错误。

    演示:

    class Program
    {
        static void Main(string[] args)
        {
            string json = @"
            {
                ""signals"":
                [
                    {
                        ""name"":""1"",
                        ""att1"":""44"",
                        ""att2"":""0"",
                        ""att3"":""18"",
                        ""size"":10,
                        ""points"":[-79,-29,-9,-23,27,-110,-39,-22,-32,-2]
                    },
                    {
                        ""name"":""2"",
                        ""att1"":""46"",
                        ""att2"":""0"",
                        ""att3"":""12"",
                        ""size"":10,
                        ""points"":[36,37,37,35,38,41,41,45,39,41]
                    }
                ],
                ""options"":""opt1 opt2"",
                ""fields"":""myfields"",
                ""lapse"":""somelapse""
            }";
    
            InputJson a = JsonConvert.DeserializeObject<InputJson>(json);
            Console.WriteLine("signals: " + a.signals);
            Console.WriteLine("options: " + a.options);
            Console.WriteLine("fields: " + a.fields);
            Console.WriteLine("lapse: " + a.lapse);
        }
    }
    

    输出:

    signals: [{"name":"1","att1":"44","att2":"0","att3":"18","size":10,"points":[-79,-29,-9,-23,27,-110,-39,-22,-32,-2]},{"name":"2","att1":"46","att2":"0","att3":"12","size":10,"points":36,37,37,35,38,41,41,45,39,41]}]
    options: opt1 opt2
    fields: myfields
    lapse: somelapse
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-09
      相关资源
      最近更新 更多