首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >StackOverflowException on JsonConvert.DeserializeObject

StackOverflowException on JsonConvert.DeserializeObject
EN

Stack Overflow用户
提问于 2016-10-11 14:52:04
回答 2查看 1.9K关注 0票数 3

我正在编写一个解决方案,其中包含一个ASP.NET Web (.NET 4.6.2),也就是后端,Web客户端实现PCLPCL即中间件,Xamarin.Forms项目也是前端。在最近对web进行了更改之后,当我试图在我的前端反序列化JSON响应时,我现在总是得到一个StackOverflowException。具体内容如下:

代码语言:javascript
复制
result_ = JsonConvert.DeserializeObject<ObservableCollection<Employee>>(Encoding.UTF8.GetString(responseData_, 0, responseData_.Length));

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

EmployeesManager.cs (在中间件中)

代码语言:javascript
复制
private Image _image = new Image();

ImagesManager.cs (在中间件中)

代码语言:javascript
复制
private Employee _employee = new Employee();

下面是更多代码:

模型(在Web中):

代码语言:javascript
复制
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生成的:

代码语言:javascript
复制
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.Forms项目使用Web客户端实现。这种行为在所有平台上都是一样的。不过,只有iOS和UWP识别堆栈溢出。在Android上,当我从Web读取数据时,应用程序就会毫无例外地关闭。

如果有人想看到更多的代码,我可以准备一个包含所请求代码的小包。将它们全部张贴在这里将完全打破可读性。

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-10-12 08:07:55

我跟踪了Oxidda,David和EJoshuaS的答案。

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

我尝试将JsonIgnore放在中间件()内的Image上的Employee属性上。奇怪的是,这并没有解决问题。我仍然得到了堆栈溢出和属性后面的私有变量。现在,我将JsonIgnore放在Web (后端)中图像类的Employee导航属性以及设备类的Employee导航属性上。然后,我将导航属性(映像类中的Employee,设备类中的Employee)完全从API客户机(中间件)中删除,因为这些属性的JSON将永远不会被接收,因为API已经忽略了这些属性。错误现在消失了,最重要的是,我的请求和响应速度有了很大的提高。虽然Web (后端)运行良好,并且在关系上没有问题,但可选模型上的导航属性引入了大量的开销。类非常小,数据库的表几乎是空的,但影响似乎很大。

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

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

  1. 使用EntityFramework6创建了一个ASP.NET Web (.NET 4.6.2)项目,添加了关系模型,添加了DbContext。支架式异步控制器。Web已经完成。注意,在JSon中使用实体框架时,不应该使用延迟加载。相反,我在控制器中使用热切的加载。
  2. 创建的PCL与Xamarin PCL使用的配置文件相同。因此,它与Xamarin解决方案兼容,但也与所有其他标准.NET解决方案兼容。
  3. 在Web的基础上,用NSwag生成中间件API。您基本上将您的API.dll加载到程序中,选择您的设置,并在C#中接收到与PCL兼容的客户端实现。API是相当高级别和异步的,因此您可以在任何.NET前端轻松地使用您的API。
  4. 添加您选择的前端解决方案。通过客户端API轻松地使用您的数据。

基本上,您可以在Web中编写一些属性(+配置JSon序列化程序和DbContext),然后生成整个后端和中间件的其余部分。我爱死它了。

票数 1
EN

Stack Overflow用户

发布于 2016-10-11 14:57:22

我以前也遇到过这种情况,这是由于物体之间的循环引用造成的。您有一个员工引用图片和图像引用员工。

尝试在Image类中将一个[JsonIgnore]放在Employee属性的上方。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39980162

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档