[英]Handling Master Data on (De-)Serialization with JSON.net
使用JSON.NET,我陷入了關於GET和POST操作的MasterData問題。
以電影為例,在反序列化之前可以在GET操作上獲取的JSON如下:
{
“movie”: {
“name”:”bad boys”,
”genre”: {
“id”:"1",
”name”:”thriller”
}
}
}
但是,在POST操作中,我想構造如下的序列化字符串:
{
“movie”: {
“name”:”bad boys”,
”genre”:"1"
}
}
如您所見,通過GET操作,我需要反序列化整個對象,而在進行POST序列化時,我只需要添加ID,但具有相同的JsonPropertyName。
解決這種情況的最干凈的方法是什么? 我一直在嘗試使用IContractResolver和IReferenceResolver,但是它們都還沒有把我帶到那里。 也一直嘗試使用屬性名作為以下示例:
[JsonProperty(PropertyName = "genre")]
public Genre Genre { get; set; }
[JsonProperty(PropertyName = "genre")]
public string GenreId { get { return Genre != null ? Genre.Id : 0; } }
我也嘗試過使用ShouldSerialize [MemberName]和ShouldDeserialize [MemberName]情況,但是這些情況例外,說我不能使用兩個具有相同名稱的屬性,這在某種程度上是合乎邏輯的。
現在,我剩下的唯一想法是使用DTO進行序列化,但我寧願選擇比該解決方案更干凈的東西。 歡迎提出建議!
您可以編寫一個自定義轉換器。
public class GenreConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Genre);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return JObject.Load(reader).ToObject<Genre>();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var genre = value as Genre;
writer.WriteValue(genre.id);
}
}
您現在所需要的只是使用JsonConverter
屬性
public class Movie
{
public string Name { get; set; }
[JsonConverter(typeof(GenreConverter))]
public Genre Genre { get; set; }
}
為此使用定制轉換器 。 您要檢查genre
屬性的genre
並將其作為object
或int
讀取。
我認為,使用DTO 是最干凈的解決方案。 由於GET / POST的模型不同,因此理想情況下需要兩個單獨的模型。 我濫用了NullValueHandling.Ignore
序列化程序設置,意味着您可以在兩種情況下使用相同的模型, NullValueHandling.Ignore
是您不介意始終在Genre
上擁有Id
屬性:
class MovieJsonWrapper
{
[JsonProperty("movie")]
public Movie Movie { get; set; }
}
class Movie
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("genre")]
public Genre Genre { get; set; }
}
class Genre
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
}
然后,我們可以將其用於:
var movie = new Movie
{
Name = "bad boys",
Genre = new Genre
{
Id = "1"
}
};
var movieJsonWrapper = new MovieJsonWrapper { Movie = movie };
var jsonSerializerSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
var json = JsonConvert.SerializeObject(movieJsonWrapper, jsonSerializerSettings);
這將產生以下結果:
{
"movie": {
"name": "bad boys",
"genre": {
"id": "1"
}
}
}
同樣,我們可以使用以下方法反序列化GET響應:
var result = JsonConvert.DeserializeObject<MovieJsonWrapper>(raw);
如果確實需要在發布時放棄流派上的Id
屬性,那么您將需要其他模型。 該解決方案減少了樣板的數量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.