我正在编写一个解决方案,其中包含一个ASP.NET Web (.NET 4.6.2),也就是后端,Web客户端实现PCLPCL即中间件,Xamarin.Forms项目也是前端。在最近对web进行了更改之后,当我试图在我的前端反序列化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中):
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.Forms项目使用Web客户端实现。这种行为在所有平台上都是一样的。不过,只有iOS和UWP识别堆栈溢出。在Android上,当我从Web读取数据时,应用程序就会毫无例外地关闭。
如果有人想看到更多的代码,我可以准备一个包含所请求代码的小包。将它们全部张贴在这里将完全打破可读性。
我使用Newtonsoft Json.NET,实体框架6,NSwag 6,Xamarin.Forms v2.3.2.127。
发布于 2016-10-12 08:07:55
我跟踪了Oxidda,David和EJoshuaS的答案。
以下是完整文档的完整解决方案:
我尝试将JsonIgnore放在中间件()内的Image上的Employee属性上。奇怪的是,这并没有解决问题。我仍然得到了堆栈溢出和属性后面的私有变量。现在,我将JsonIgnore放在Web (后端)中图像类的Employee导航属性以及设备类的Employee导航属性上。然后,我将导航属性(映像类中的Employee,设备类中的Employee)完全从API客户机(中间件)中删除,因为这些属性的JSON将永远不会被接收,因为API已经忽略了这些属性。错误现在消失了,最重要的是,我的请求和响应速度有了很大的提高。虽然Web (后端)运行良好,并且在关系上没有问题,但可选模型上的导航属性引入了大量的开销。类非常小,数据库的表几乎是空的,但影响似乎很大。
TL;DR:消除了源处循环引用的可能性。对客户端的镜像更改。问题得到解决,并得到了巨大的提速。。
如果有人对我的解决方案的完整设计感兴趣,这里有一个小摘要。我非常喜欢它。
基本上,您可以在Web中编写一些属性(+配置JSon序列化程序和DbContext),然后生成整个后端和中间件的其余部分。我爱死它了。
发布于 2016-10-11 14:57:22
我以前也遇到过这种情况,这是由于物体之间的循环引用造成的。您有一个员工引用图片和图像引用员工。
尝试在Image类中将一个[JsonIgnore]放在Employee属性的上方。
https://stackoverflow.com/questions/39980162
复制相似问题