@Alan Buchanan shows 一种很好的简单方法来实现您在问题中描述的内容。但是,如果您不想为类添加其他属性,则需要使用自定义 JsonConverter 来代替。这是一个如何编写它的示例:
class PersonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Person);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Person person = (Person)value;
JObject result = new JObject();
result.Add("id", person.Id);
result.Add("fullname", (person.FirstName + " " + person.LastName).Trim());
result.Add("address", (person.Address1 + " " + person.Address2).Trim());
result.WriteTo(writer);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject obj = JObject.Load(reader);
Person person = new Person();
person.Id = (int)obj["id"]; // assuming id will always be present in the JSON
string fullName = (string)obj["fullname"];
if (fullName != null)
{
string[] parts = fullName.Split(new char[] { ' ' }, 2);
// if there's only 1 part, I'm assuming it is the first name
if (parts.Length > 0)
person.FirstName = parts[0];
if (parts.Length > 1)
person.LastName = parts[1];
}
person.Address1 = (string)obj["address"]; // don't bother trying to split address
return person;
}
}
您会注意到PersonConverter 类包含三个方法,所有这些方法都需要由它所继承的JsonConverter 抽象基类来实现:CanConvert、ReadJson 和WriteJson。
CanConvert 方法告诉 Json.Net 该转换器处理 Person 对象。 Json.Net 可能会也可能不会调用此方法,具体取决于您使用转换器的方式。稍后会详细介绍。
WriteJson 负责在序列化过程中为目标对象创建 JSON。您可以在这里看到我在内部使用JObject 来使用Person 类中的数据构建JSON。你也可以直接在 writer 上调用方法,而不是使用 JObject,但我觉得那样会比较麻烦。
ReadJson 处理相反的情况:在反序列化期间从 JSON 重构对象。同样,我使用JObject 作为中介从读取器获取数据,然后将其拆分到新的@987654340@ 实例中。
如果你只需要序列化而不需要反序列化,你可以覆盖CanRead返回false,然后让ReadJson抛出一个NotImplementedException。同样,如果您只需要反序列化而不需要序列化,则可以覆盖 CanWrite 属性。
有两种方法可以使用JsonConverter:您可以将实例传递给序列化/反序列化方法(通过方法参数或JsonSerializerSettings)...
string json = JsonConvert.SerializeObject(p, new PersonConverter());
...或者您可以使用[JsonConverter] 属性将转换器绑定到您的类:
[JsonConverter(typeof(PersonConverter))]
public class Person
{
...
}
如果您使用前一种方法,那么 Json.Net 会调用 CanConvert 来确定您的转换器可以处理的类型。如果您使用该属性,则永远不会调用 CanConvert,因为 Json.Net 假定您已在目标类的属性中指定了正确的转换器类型。
这是一个往返演示:https://dotnetfiddle.net/EGok23