我正在 UWP 应用中使用 ef 核心数据库,并且在使用 Newtonsoft JSON 序列化包含列表的列表时遇到一些问题。
对于最小示例,请考虑来自微软的UWP教程,其中包含以下代码
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Post { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Filename=minexample.db");
}
}
当我现在想通过以下方式序列化一些数据时:
using (var db = new BloggingContext())
{
var dbPost = db.Blogs.Include(x => x.Post).ToList();
var serialized = JSONClass.Serialize(dbPost);
}
我收到System.StackOverflowException
类型的错误,mscorlib.ni.dll
我进入了无限循环。正如用户 alanh 在评论中提到的,可以通过将ReferenceLoopHandling
设置为JsonSerializerSettings
中的ReferenceLoopHandling.Ignore
来修复此行为。
我宁愿在序列化博客时只将每个帖子的ID
存储为List<int>
而不是List<Post>
。
如果给定了数据库,为什么要序列化?我想共享特定的数据库条目,需要序列化它们。我还考虑这样做是为了与OneDrive
同步,因此在不同时间(单个用户)在不同设备上编辑不同的数据库条目时不会发生冲突。
将这行代码添加到启动类中,可以防止循环问题
services.AddMvc().AddJsonOptions(options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
然后,可以将[JsonIgnore]
属性用于不希望序列化的所有属性。
或者,可以通过扩展JsonConverter
类并实现自己的WriteJson, ReadJson
和CanConvert
方法来实现自己的序列化程序,如下所示:
实现自己的序列化程序