[英]How to make JSON.Net serializer to call ToString() when serializing a particular type?
我使用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<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;
}
往返演示: https : //dotnetfiddle.net/fd4EG4
如果不打算大規模使用,有一種更快的方法可以做到這一點,在下面的示例中,它是為RecordType屬性完成的
[JsonIgnore]
public RecordType RecType { get; set; }
[JsonProperty(PropertyName = "RecordType")]
private string RecordTypeString => RecType.ToString();
您可以使用以下代碼簡單地嘗試使用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
});
我沒有時間測試我的解決方案,但它應該工作。 假設您使用的所有類都是您自己的,為什么不在所有類上執行ToString覆蓋,並且需要使用Newtonsoft.Json序列化程序的類只能在ToString方法中序列化並返回。 這樣,當您想要獲取對象的序列化字符串時,您始終可以調用ToString。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.