You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Json.NET自定义转换器序列化含DataSet对象时JSON无效错误排查

问题分析与解决:嵌套DataSet序列化时的JSON结构错误

你的问题出在DataSetConverter的WriteJson方法里使用了writer.WriteRaw()——这个方法会直接把序列化后的XML转JSON字符串原封不动输出,完全忽略了JsonWriter当前的状态。当你序列化包含DataSet的TestClass对象时,JsonWriter正处于写入属性值的状态(正在处理Inserts属性),直接用WriteRaw输出完整的JSON结构会破坏整个JSON的语法,导致你看到的错误。

修复方案

把WriteRaw替换为正确的序列化方式:先将XNode序列化为JToken,再让JsonSerializer来处理这个JToken,这样它会自动适配当前的JSON结构上下文。

修正后的DataSetConverter代码如下:

class DataSetConverter : JsonConverter<DataSet>
{
    public override DataSet ReadJson(JsonReader reader, Type objectType, DataSet existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        DataSet dataSet = new DataSet();
        JObject jObject = JObject.Load(reader);
        string json = jObject.ToString();
        XDocument document = JsonConvert.DeserializeXNode(json);
        using (MemoryStream memoryStream = new MemoryStream())
        using (StreamWriter streamWriter = new StreamWriter(memoryStream))
        {
            streamWriter.Write(document.ToString(SaveOptions.None));
            streamWriter.Flush();
            memoryStream.Position = 0;
            dataSet.ReadXml(memoryStream);
        }
        return dataSet;
    }

    public override void WriteJson(JsonWriter writer, DataSet dataSet, JsonSerializer serializer)
    {
        using (MemoryStream memoryStream = new MemoryStream())
        {
            dataSet.WriteXml(memoryStream, XmlWriteMode.WriteSchema);
            memoryStream.Seek(0, SeekOrigin.Begin);
            using (StreamReader reader = new StreamReader(memoryStream))
            {
                XDocument document = XDocument.Parse(reader.ReadToEnd());
                // 替换WriteRaw为JToken序列化,让JsonWriter正确处理嵌套结构
                JToken token = JsonConvert.SerializeXNode(document, Formatting.Indented, false);
                serializer.Serialize(writer, token);
            }
        }
    }
}

为什么原来的写法不行?

当你单独序列化DataSet时,JsonWriter处于根节点状态,直接用WriteRaw输出完整的JSON对象是没问题的;但当序列化TestClass时,JsonWriter正在处理Inserts这个属性,需要输出的是该属性对应的值——而WriteRaw直接输出了一个完整的JSON对象(带{}),这会导致JsonWriter的状态逻辑冲突:它原本在准备写入属性值,突然收到了一个完整的对象结构,自然会抛出"Token PropertyName in state Property would result in an invalid JSON object"的错误。

用serializer.Serialize(writer, token)的话,JsonWriter会根据当前状态正确处理这个JToken,确保嵌套结构的语法完全合规。

验证修复

修改后,你再序列化TestClass对象:

TestClass testClass = new TestClass { Inserts = originalInserts, SomethingElse = "Me" };
string json = JsonConvert.SerializeObject(testClass, Formatting.Indented, new DataSetConverter());
// 反序列化也能正常工作
TestClass deserialized = JsonConvert.DeserializeObject<TestClass>(json, new DataSetConverter());

就不会再出现错误了。

内容的提问来源于stack exchange,提问作者Martin Robins

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:16:09