我必须解析(并最终重新序列化)一些狡猾的JSON。它看起来像这样:
{
name: "xyz",
id: "29573f59-85fb-4d06-9905-01a3acb2cdbd",
status: "astatus",
color: colors["Open"]
},
{
name: "abc",
id: "29573f59-85fb-4d06-9905-01a3acb2cdbd",
status: "astatus",
color: colors["Open"]
}
这里有很多问题-从最严重的问题开始。
color: colors["Open"]
WTF甚至是吗?如果我放弃“颜色”,那么我可以得到一系列的字符串,但是我不能调整以开箱即用。
它是一个没有方括号的数组。我可以将它们包裹起来以解决此问题。但是有没有一种现成的支持方式?
属性没有引号。反序列化对于这些很好,但是重新序列化不是一个骰子。
关于处理此结构的任何建议?
按顺序回答您的问题#1-#3:
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中获得原始的躲避值。
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
。
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小提琴展示了所有这些动作。
我试图写一个程序,读取一串文本,并打印文本中的所有直方图及其频率。 输入示例: 相应的输出: 当我尝试这个示例输入时,它输出 我该如何修复它,使它不会有括号和逗号?
有没有一种方法可以正确地反序列化以双引号开头和结尾的JSON字符串? 数据以流的形式输入(来自AWS S3对象)。这是流的内容(注意开头和结尾的双引号字符): JsonSerializer似乎没有正确地反序列化它。但是,对于以下内容,其工作原理与预期一致: 以下是片段:
问题内容: 我有这个: JSONLint表示这是完全有效的json。但是执行时出现错误。 但是,如果我将代码更改为: (请注意双反斜杠) 它可以工作,但是现在JSONLint表示。 有人可以帮助您了解这种行为吗? 问题答案: 有线格式和您必须在代码中编写的格式之间是有区别的。当您在代码中声明此代码时,您需要在文字中使用双-\,以便字符串获得一个反斜杠(否则,它将\\解释为一个转义序列,仅声明一个“
我得到了这样的回应 因此,在使用时,由于前面有文本“stripe\product json:”,所以我得到了一个错误 请帮忙
问题内容: 我有一个包含数字的字符串列表,但找不到找到对它们进行排序的好方法。 例如,我得到这样的东西: 用的方法。 我知道我可能需要以某种方式提取数字,然后对列表进行排序,但是我不知道如何以最简单的方式进行操作。 问题答案: 也许您正在寻找人工排序(也称为自然排序): 产量 PS。我已经更改了答案,以使用Toothy的自然排序实现(在此处发表评论),因为它比我的原始答案快得多。 如果您希望使用浮
问题内容: 我试图将字符串传递给json对象,并且它可以工作。但是json中有一些反斜杠和双引号!如何删除它们? 我正在使用c#。这是我的代码。 当我在控制器中返回此函数时,我得到的结果是这样的 “ {\”状态\“:\”成功\“}” 问题答案: 发生这种情况是因为您正在手动(以代码形式)将数据序列化为JSON,并且当您从控制器返回数据时,框架再次序列化了相同的东西,它已经是json格式的字符串了!