如果重写ToString,JSON.NET序列化

Joh*_*day 7 c# serialization json json.net

我有一组复杂的业务对象,我想序列化到Json用于Web服务.我目前正在使用DataContractJsonSerializer来生成Json,但它在反序列化时很好,因为默认的XmlReader无法处理Base64字符串.

在阅读了Json.Net的许多正面评论后,我决定尝试一下.令人惊讶的是,如果业务对象重写ToString()方法,最简单的情况会产生错误的输出.它不是生成JSON,而是简单地发出字符串值.

例如,以下语句仅生成一个字符串,因为序列化程序似乎将对象视为一个简单的字符串.

public class MyClass {
    public string Title{get;set;}
    public override ToString(){ return Title; }
    public string ToJson(){ 
        return JsonConvert.SerializeObject(this); 
    }
}
Run Code Online (Sandbox Code Playgroud)

而不是json格式化输出,我得到的只是标题字符串.我是否必须以某种特殊方式标记对象以避免这种情况?由于业务对象层次结构包含许多覆盖ToString()的对象,我宁愿避免引入特殊属性等.

wex*_*man 5

您的实际类是否可能附加了 TypeConverterAttribute?我刚刚遇到了完全相同的问题,并发现 TypeConverterAttribute 导致了此问题。在这种情况下,这可能会有所帮助(至少对我来说)。

这是非常糟糕的,因为您可能会无意中破坏您的程序(通过简单地添加 TypeConverter 可能用于在 PropertyGrid 中显示对象)而不会收到编译器警告...

using Newtonsoft.Json;
using System;
using System.ComponentModel;

namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {
            var with = new WithTypeConverter() { Bla = 12, Blub = "With" };
            var without = new WithoutTypeConverter() { Bla = 12, Blub = "Without" };

            Console.WriteLine(with);
            Console.WriteLine(JsonConvert.SerializeObject(with));

            Console.WriteLine(without);
            Console.WriteLine(JsonConvert.SerializeObject(without));
            Console.ReadKey();
        }
    }

    public class baseClass
    {
        public int Bla { get; set; }
        public string Blub { get; set; }

        public override string ToString()
        {
            return String.Format("{0}: {1}", this.GetType().Name, Blub);
        }
    }

    [TypeConverter(typeof(ExpandableObjectConverter))]
    public class WithTypeConverter : baseClass
    {
    }

    public class WithoutTypeConverter : baseClass
    {
    }
}
Run Code Online (Sandbox Code Playgroud)


Str*_*ior 2

您的测试可能是错误的。我刚刚在 LINQPad 中运行了以下代码:

void Main()
{
    new MyClass{Title = "hi"}.ToJson().Dump();
}

// Define other methods and classes here
public class MyClass {
    public string Title{get;set;}
    public override string ToString(){ return Title; }
    public string ToJson(){ 
        return JsonConvert.SerializeObject(this); 
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

{"Title":"hi"}
Run Code Online (Sandbox Code Playgroud)