StackOverflowException on JsonConvert.DeserializeObject

本文关键字:DeserializeObject JsonConvert on StackOverflowException | 更新日期: 2023-09-27 18:12:27

我正在编写一个包含ASP的解决方案。. NET Web API(。. NET 4.6.2)即后端,Web API客户端实现PCL即中间件和Xamarin。窗体项目即前端。在最近对我的web api进行更改后,当我试图在我的前端反序列化JSON响应时,我现在总是得到StackOverflowException。具体行为:

result_ = JsonConvert.DeserializeObject<ObservableCollection<Employee>>(Encoding.UTF8.GetString(responseData_, 0, responseData_.Length));

当我在这里调试时,我看到程序在两行之间跳转,直到发生溢出:

EmployeesManager.cs(在中间件中)

private Image _image = new Image();

ImagesManager.cs(在中间件)

private Employee _employee = new Employee();

下面是更多的代码:

模型(在Web API):

public class Employee
{
    public int Id { get; set; }
    // OMITTED PROPS
    public int? ImageId { get; set; }
    public Image Image { get; set; }
    public ICollection<Device> Devices { get; set; }
    public int? TeamId { get; set; }
    public Team Team { get; set; }
}
public class Image
{
    [Key]
    public int Id { get; set; }
    [Required]
    public byte[] Data { get; set; }
    public int EmployeeId { get; set; }
    public Employee Employee { get; set; }
}

客户端实现(中间件)中的模型。它们是用Nswag:

生成的
public partial class Employee : INotifyPropertyChanged
{
    private int _id;
    private int? _imageId;
    private Image _image = new Image(); // THIS LINE IS PART OF THE OVERFLOW
    private ObservableCollection<Device> _devices;
    private int? _teamId;
    private Team _team = new Team();
    // OMITTED PROPS
    [JsonProperty("image", Required = Required.Default, NullValueHandling = NullValueHandling.Ignore)]
    public Image Image
    {
        get { return _image; }
        set
        {
            if (_image != value)
            {
                _image = value;
                RaisePropertyChanged();
            }
        }
    }
public partial class Image : INotifyPropertyChanged
{
    private int _id;
    private int _employeeId;
    private Employee _employee = new Employee(); // THIS LINE IS PART OF THE STACK OVERFLOW
    private byte[] _data;
    // OMITTED PROPS 
    [JsonProperty("employee", Required = Required.Default, NullValueHandling = NullValueHandling.Ignore)]
    public Employee Employee
    {
        get { return _employee; }
        set
        {
            if (_employee != value)
            {
                _employee = value;
                RaisePropertyChanged();
            }
        }
    }

我通过Xamarin使用Web API客户端实现。形式的项目。所有平台上的行为都是一样的。不过,只有iOS和UWP能够识别Stack Overflow。在Android上,当我从Web API读取数据时,应用程序只是关闭而没有异常。

如果有人想看到更多的代码,我可以准备一个小包包含所要求的代码。把它们都贴在这里会完全破坏可读性。

我使用Newtonsoft Json。. NET,实体框架6,NSwag 6, Xamarin。v2.3.2.127形式。

StackOverflowException on JsonConvert.DeserializeObject

我以前也遇到过这种情况;这是由于物体之间的循环引用。你有一个雇员引用图像和图像引用雇员。

尝试在图像类Image的Employee属性上方放置一个[JsonIgnore]

我遵循了Oxidda、David和ejoshua的答案。

下面是完整文档的完整解决方案:

我试着把JsonIgnore放在中间件(Web API客户端PCL)内部图像类的Employee属性上。奇怪的是,这并没有解决问题。我仍然有堆栈溢出与私有变量背后的属性。现在我把JsonIgnore放在Web API(后端)中Image类的Employee导航属性上,也放在Device类的Employee导航属性上。然后,我从API客户端(中间件)中完全删除了导航属性(图像类中的Employee和设备类中的Employee),因为这些属性的JSON现在将永远不会被接收,因为API已经忽略了这些属性。现在这个错误已经消失了,最重要的是,我的请求和响应速度得到了显著提升。看起来,尽管Web API(后端)运行良好,关系也没有问题,但可选模型上的那些导航属性带来了大量的开销。类非常小,数据库的表几乎是空的,但影响似乎是巨大的。

TL;DR:消除了源处循环引用的可能性。将更改镜像到客户端。问题解决了,速度也大大提高了。

如果有人对我的解决方案的完整设计感兴趣,这里有一个小总结。我非常喜欢它。

  1. 创建ASP。. NET Web API(。. NET 4.6.2)项目与实体框架6。添加带有关系的模型,添加DbContext。脚手架式异步控制器。Web API完成了。注意,在使用JSon实体框架时不应该使用延迟加载。相反,我在控制器中使用即时加载。
  2. 创建与Xamarin PCL使用相同配置文件的PCL。因此,它与Xamarin解决方案兼容,也与所有其他标准。net解决方案兼容。
  3. 基于Web API,使用NSwag生成中间件API。你只需将你的API.dll加载到程序中,选择你的设置,然后你就会收到一个完整的pcl兼容的c# Web API客户端实现。API是相当高级和异步的,所以你可以在任何。net前端轻松地使用你的API。
  4. 添加您选择的前端解决方案。通过客户机API轻松地使用数据。

基本上你只需要在Web API中编写一些属性(+配置JSon序列化器和DbContext),整个后端和中间件的其余部分就会生成。我喜欢它。

相关文章:
  • 没有找到相关文章