如何在序列化特定类型时使JSON.Net序列化程序调用ToString()?

我正在使用Newtonsoft.Json序列化程序将C#类转换为JSON。 对于某些类,我不需要序列化程序将实例添加到单个属性,而只需在对象上调用ToString,即

public class Person { public string FirstName { get; set; } public string LastName { get; set; } public override string ToString() { return string.Format("{0} {1}", FirstName, LastName ); } } 

我应该怎么做才能将Person对象序列化为ToString()方法的结果? 我可能有很多像这样的类,所以我不想最终得到一个特定于Person类的序列化程序,我希望有一个可以适用于任何classe(通过属性我猜)。

您可以使用自定义JsonConverter轻松完成此JsonConverter

 public class ToStringJsonConverter : JsonConverter { public override bool CanConvert(Type objectType) { return true; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { writer.WriteValue(value.ToString()); } public override bool CanRead { get { return false; } } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException(); } } 

要使用转换器,请使用[JsonConverter]属性来装饰需要序列化为字符串的任何类,如下所示:

 [JsonConverter(typeof(ToStringJsonConverter))] public class Person { ... } 

这是一个演示转换器的演示:

 class Program { static void Main(string[] args) { Company company = new Company { CompanyName = "Initrode", Boss = new Person { FirstName = "Head", LastName = "Honcho" }, Employees = new List { new Person { FirstName = "Joe", LastName = "Schmoe" }, new Person { FirstName = "John", LastName = "Doe" } } }; string json = JsonConvert.SerializeObject(company, Formatting.Indented); Console.WriteLine(json); } } public class Company { public string CompanyName { get; set; } public Person Boss { get; set; } public List Employees { get; set; } } [JsonConverter(typeof(ToStringJsonConverter))] public class Person { public string FirstName { get; set; } public string LastName { get; set; } public override string ToString() { return string.Format("{0} {1}", FirstName, LastName); } } 

输出:

 { "CompanyName": "Initrode", "Boss": "Head Honcho", "Employees": [ "Joe Schmoe", "John Doe" ] } 

如果您还需要能够从字符串转换回对象,则可以在转换器上实现ReadJson方法,以便它查找public static Parse(string)方法并调用它。 注意:请务必更改转换器的CanRead方法以返回true (或者只删除CanRead重载),否则将永远不会调用ReadJson

 public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { MethodInfo parse = objectType.GetMethod("Parse", new Type[] { typeof(string) }); if (parse != null && parse.IsStatic && parse.ReturnType == objectType) { return parse.Invoke(null, new object[] { (string)reader.Value }); } throw new JsonException(string.Format( "The {0} type does not have a public static Parse(string) method that returns a {0}.", objectType.Name)); } 

当然,为了实现上述function,您还需要确保在要转换的每个类上实现合适的Parse方法(如果它尚不存在)。 对于上面显示的示例Person类,该方法可能如下所示:

 public static Person Parse(string s) { if (string.IsNullOrWhiteSpace(s)) throw new ArgumentException("s cannot be null or empty", "s"); string[] parts = s.Split(new char[] { ' ' }, 2); Person p = new Person { FirstName = parts[0] }; if (parts.Length > 1) p.LastName = parts[1]; return p; } 

往返演示: https : //dotnetfiddle.net/fd4EG4

如果不打算大规模使用,有一种更快的方法,在下面的示例中,它是为RecordType属性完成的

 [JsonIgnore] public RecordType RecType { get; set; } [JsonProperty(PropertyName = "RecordType")] private string RecordTypeString => RecType.ToString(); 

您可以使用以下代码尝试使用Newtonsoft的JSON构建器库和Serilaize类型为Person的对象:

 Dictionary collection = new Dictionary() { {"First", new Person()}, {"Second", new Person()}, }; string json = JsonConvert.SerializeObject(collection, Formatting.Indented, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple }); 

我没有时间测试我的解决方案,但它应该工作。 假设您使用的所有类都是您自己的,为什么不在所有类上执行ToString覆盖,并且需要使用Newtonsoft.Json序列化程序的类只能在ToString方法中序列化并返回。 这样,当您想要获取对象的序列化字符串时,您始终可以调用ToString。