我使用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(通过属性我猜)。
答案 0 :(得分:43)
您可以使用自定义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<Person>
{
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<Person> 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));
}
当然,为了使上述工作正常,您还需要确保在要转换的每个类上实现合适的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;
}
答案 1 :(得分:7)
如果不打算大规模使用,有一种更快的方法可以做到这一点,在下面的示例中,它是针对 RecordType 属性完成的
[JsonIgnore]
public RecordType RecType { get; set; }
[JsonProperty(PropertyName = "RecordType")]
private string RecordTypeString => RecType.ToString();
答案 2 :(得分:0)
您只需尝试使用Newtonsoft的JSON构建器库,并使用以下代码对Person类型的对象进行Serilaize:
Dictionary<string, object> collection = new Dictionary<string, object>()
{
{"First", new Person(<add FirstName as constructor>)},
{"Second", new Person(<add LastName as constructor>)},
};
string json = JsonConvert.SerializeObject(collection, Formatting.Indented, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All,
TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
});
答案 3 :(得分:-1)
我没有时间测试我的解决方案,但它应该有效。假设您使用的所有类都是您自己的,为什么不在所有类上执行ToString覆盖,并且需要使用Newtonsoft.Json序列化程序的类只能在ToString方法中序列化并返回。这样,当你想获得对象的序列化字符串时,你总是可以调用ToString。