栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何反序列化狡猾的JSON(带有不正确的引号字符串和缺少的括号)?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何反序列化狡猾的JSON(带有不正确的引号字符串和缺少的括号)?

按顺序回答您的问题#1-#3:

  1. Json.NET不支持以以下形式读取狡猾的属性值
    colors["Open"]
    (如您所正确指出的那样,它违反了JSON标准)。

相反,您将需要手动修复这些值,例如通过某种方式

Regex

    var regex = new Regex(@"(colors[)(.*)(])");var fixedJsonString = regex.Replace(jsonString,     m => string.Format(@"""{0}{1}{2}""", m.Groups[1].Value, m.Groups[2].Value.Replace(""", "\""), m.Groups[3].Value));

这会将

color
属性值更改为正确转义的JSON字符串:

    color: "colors["Open"]"

但是,Json.NET确实具有通过在custom内调用来
编写
狡猾的属性值的功能。

JsonWriter.WriteRawValue()
JsonConverter


定义以下转换器:

    public class RawStringConverter : JsonConverter{    public override bool CanConvert(Type objectType)    {        return objectType == typeof(string);    }    public override bool CanRead { get { return false; } }    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)    {        throw new NotImplementedException();    }    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)    {        var s = (string)value;        writer.WriteRawValue(s);    }}

然后定义

RootObject
如下:

    public class RootObject{    public string name { get; set; }    public string id { get; set; }    public string status { get; set; }    [JsonConverter(typeof(RawStringConverter))]    public string color { get; set; }}

然后,当重新序列化时,您将在JSON中获得原始的躲避值。

  1. 在10.0.3之后的下一个Json.NET版本中,将支持反序列化以逗号分隔的JSON,而无需使用方括号。有关详细信息,请参见问题1396和问题1355。您需要进行设置
    JsonTextReader.SupportMultipleContent = true
    以使其起作用。

因此,您可以按以下方式反序列化JSON:

    List<RootObject> list;using (var reader = new StringReader("[").Concat(new StringReader(fixedJsonString)).Concat(new StringReader("]")))using (var jsonReader = new JsonTextReader(reader)){    list = JsonSerializer.CreateDefault().Deserialize<List<RootObject>>(jsonReader);}

(或者,您可以使用

[
和手动将JSON字符串括起来
]
,但我更喜欢不涉及复制可能很大的字符串的解决方案。)

重新序列根集合,而不外括号,如果你序列化的每个项目单独利用自身可能

JsonTextWriter
CloseOutput =false
。您还可以
,
在每个序列化项目之间手动将a写入每个用户
TextWriter
共享的基础
JsonTextWriter

  1. 如果设置,则可以序列化JSON属性名称而无需使用引号引起来
    JsonTextWriter.QuoteName = false

因此,要重新序列化

List<RootObject>
不带引号的属性名称或大括号,请执行以下操作:

    var sb = new StringBuilder();bool first = true;using (var textWriter = new StringWriter(sb)){    foreach (var item in list)    {        if (!first)        { textWriter.WriteLine(",");        }        first = false;        using (var jsonWriter = new JsonTextWriter(textWriter) { QuoteName = false, Formatting = Formatting.Indented, CloseOutput = false })        { JsonSerializer.CreateDefault().Serialize(jsonWriter, item);        }    }}var reserializedJson = sb.ToString();

样本.Net小提琴展示了所有这些动作。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/609081.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号