将字符串值反序列化为 ienumerable<t> in asp.net core 3
Deserialize string values to ienumerable<t> in asp.net core 3
我想将此 json 数据反序列化为 Result class 并将 3 个图书值(FirstBook、SecondBook、ThirdBook)放入 IEnumerable<书>:
[
{
"Id": 1,
"FirstBook": "B1",
"SecondBook": "B2",
"ThirdBook": "B3",
...
},
{
"Id": 2,
"FirstBook": "BB1",
"SecondBook": "BB2",
"ThirdBook": "BB3",
...
}
]
结果Class:
public class Result
{
public int Id { get; set;}
[JsonConverter(typeof(BooksJsonConverter))]
public IEnumerable<Book> Books { get; set; }
}
图书class:
public class Book
{
public string Name { get; set; }
}
反序列化为 class Result 包含 IEnumerable< Book >
JsonConvert.DeserializeObject<IEnumerable<Result>>(json);
我想我应该创建 JsonConverter:
public class BooksJsonConverter : JsonConverter<IEnumerable<Book>>
{
public override IEnumerable<Book> ReadJson(JsonReader reader, Type objectType, IEnumerable<Book> existingValue, bool hasExistingValue, JsonSerializer serializer)
{
//What should i write here?
return new List<Book>();
}
public override void WriteJson(JsonWriter writer, Book value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
在这种情况下,BooksJsonConverter 的 ReadJson 没有被调用,但是当我添加 JsonProperty attrib 时它被调用了,但是我不知道我应该在 ReadJson 里面写什么:
public class Result
{
public int Id { get; set;}
[JsonConverter(typeof(BooksJsonConverter))]
[JsonProperty("FirstBook")]
public IEnumerable<Book> Books { get; set; }
}
问题是我应该如何将 FirstBook、SecondBook、ThirdBook 从 json 转换为结果 class 中的 IEnumerable< Book >?
由于您没有提供 Book class 结构,我将其自定义为包含一个 BookName 字段,如下所示。
public class Book
{
public string BookName { get; set; }
}
[JsonConverter(typeof(CustomeJsonConverter))]
public class Result
{
public int Id { get; set; }
public IEnumerable<Book> Books { get; set; }
}
更新
好的,jsonconverter
可以实现,方法大致相同,但是需要在Result
class而不是Book中添加自定义的jsonconverter属性,其中Book class 将被转换并添加到结果中。
代码如下:
public class HomeController : Controller
{
public IActionResult Test()
{
string json = @" [
{
'Id': 1,
'FirstBook': 'B1',
'SecondBook': 'B2',
'ThirdBook': 'B3'
},
{
'Id': 2,
'FirstBook': 'BB1',
'SecondBook': 'BB2',
'ThirdBook': 'BB3'
}
] ";
var xx = JsonConvert.DeserializeObject<IEnumerable<Result>>(json,new CustomeJsonConverter());
return Ok();
}
}
public class CustomeJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return System.Attribute.GetCustomAttributes(objectType).Any(v => v is KnownTypeAttribute);
}
public override bool CanWrite
{
get { return false; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// Load JObject from stream
JObject jObject = JObject.Load(reader);
Result result = new Result();
Dictionary<string, string> dictObj = jObject.ToObject<Dictionary<string, string>>();
List<Book> books = new List<Book>();
foreach (var obj in dictObj)
{
if (obj.Key.Contains("Book"))
{
Book book = new Book()
{
Name = obj.Value
};
books.Add(book);
}
}
result.Id = Convert.ToInt32(dictObj["Id"]);
result.Books = books.AsEnumerable();
return result;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
也可以参考this.
您可以使用 JsonExtensionData
来序列化目标对象上没有匹配属性的 JSON 文档的元素:
public class Result
{
public int Id { get; set; }
public IEnumerable<Book> Books { get; set; }
[JsonExtensionData]
private IDictionary<string, JToken> _extensionData;
[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
Books = _extensionData
.Where(d => d.Key.Equals("FirstBook") || d.Key.Equals("SecondBook"))
.Select(b => new Book { Name = b.Value.ToString() });
}
}
我想将此 json 数据反序列化为 Result class 并将 3 个图书值(FirstBook、SecondBook、ThirdBook)放入 IEnumerable<书>:
[
{
"Id": 1,
"FirstBook": "B1",
"SecondBook": "B2",
"ThirdBook": "B3",
...
},
{
"Id": 2,
"FirstBook": "BB1",
"SecondBook": "BB2",
"ThirdBook": "BB3",
...
}
]
结果Class:
public class Result
{
public int Id { get; set;}
[JsonConverter(typeof(BooksJsonConverter))]
public IEnumerable<Book> Books { get; set; }
}
图书class:
public class Book
{
public string Name { get; set; }
}
反序列化为 class Result 包含 IEnumerable< Book >
JsonConvert.DeserializeObject<IEnumerable<Result>>(json);
我想我应该创建 JsonConverter:
public class BooksJsonConverter : JsonConverter<IEnumerable<Book>>
{
public override IEnumerable<Book> ReadJson(JsonReader reader, Type objectType, IEnumerable<Book> existingValue, bool hasExistingValue, JsonSerializer serializer)
{
//What should i write here?
return new List<Book>();
}
public override void WriteJson(JsonWriter writer, Book value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
在这种情况下,BooksJsonConverter 的 ReadJson 没有被调用,但是当我添加 JsonProperty attrib 时它被调用了,但是我不知道我应该在 ReadJson 里面写什么:
public class Result
{
public int Id { get; set;}
[JsonConverter(typeof(BooksJsonConverter))]
[JsonProperty("FirstBook")]
public IEnumerable<Book> Books { get; set; }
}
问题是我应该如何将 FirstBook、SecondBook、ThirdBook 从 json 转换为结果 class 中的 IEnumerable< Book >?
由于您没有提供 Book class 结构,我将其自定义为包含一个 BookName 字段,如下所示。
public class Book
{
public string BookName { get; set; }
}
[JsonConverter(typeof(CustomeJsonConverter))]
public class Result
{
public int Id { get; set; }
public IEnumerable<Book> Books { get; set; }
}
更新
好的,jsonconverter
可以实现,方法大致相同,但是需要在Result
class而不是Book中添加自定义的jsonconverter属性,其中Book class 将被转换并添加到结果中。
代码如下:
public class HomeController : Controller
{
public IActionResult Test()
{
string json = @" [
{
'Id': 1,
'FirstBook': 'B1',
'SecondBook': 'B2',
'ThirdBook': 'B3'
},
{
'Id': 2,
'FirstBook': 'BB1',
'SecondBook': 'BB2',
'ThirdBook': 'BB3'
}
] ";
var xx = JsonConvert.DeserializeObject<IEnumerable<Result>>(json,new CustomeJsonConverter());
return Ok();
}
}
public class CustomeJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return System.Attribute.GetCustomAttributes(objectType).Any(v => v is KnownTypeAttribute);
}
public override bool CanWrite
{
get { return false; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// Load JObject from stream
JObject jObject = JObject.Load(reader);
Result result = new Result();
Dictionary<string, string> dictObj = jObject.ToObject<Dictionary<string, string>>();
List<Book> books = new List<Book>();
foreach (var obj in dictObj)
{
if (obj.Key.Contains("Book"))
{
Book book = new Book()
{
Name = obj.Value
};
books.Add(book);
}
}
result.Id = Convert.ToInt32(dictObj["Id"]);
result.Books = books.AsEnumerable();
return result;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
也可以参考this.
您可以使用 JsonExtensionData
来序列化目标对象上没有匹配属性的 JSON 文档的元素:
public class Result
{
public int Id { get; set; }
public IEnumerable<Book> Books { get; set; }
[JsonExtensionData]
private IDictionary<string, JToken> _extensionData;
[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
Books = _extensionData
.Where(d => d.Key.Equals("FirstBook") || d.Key.Equals("SecondBook"))
.Select(b => new Book { Name = b.Value.ToString() });
}
}