GVKun编程网logo

Json.NET如何避免循环引用(json 循环引用)

26

在本文中,我们将详细介绍Json.NET如何避免循环引用的各个方面,并为您提供关于json循环引用的相关解答,同时,我们也将为您带来关于c–如何使用std::shared_ptr检测或避免循环引用?、

在本文中,我们将详细介绍Json.NET如何避免循环引用的各个方面,并为您提供关于json 循环引用的相关解答,同时,我们也将为您带来关于c – 如何使用std :: shared_ptr检测或避免循环引用?、delphi – 如何避免循环单元参考?、delphi – 我有两个单元,每个单元中有一个需要彼此运行的类.如何避免循环引用?、EF 4.1-代码优先-JSON循环引用序列化错误的有用知识。

本文目录一览:

Json.NET如何避免循环引用(json 循环引用)

Json.NET如何避免循环引用(json 循环引用)

Json.NET在将对象序列化为Json字符串的时候,如果对象有循环引用的属性或字段,那么会导致Json.NET抛出循环引用异常。

 

有两种方法可以解决这个问题:

1、在对象循环引用的属性上打上[JsonIgnore]标签,例如:

public class UserProfile
{
    public string UserCode { get; set; }
    public string UserName { get; set; }
    public string MailAddress { get; set; }
    public long LoginTimeStamp { get; set; }

    [JsonIgnore]
    protected List<Role> roles;

    [JsonIgnore]
    public List<Role> Roles
    {
        get
        {
            return roles;
        }
    }
}

 

2、另一个方法是在调用Json.NET的SerializeObject方法序列化对象时,设置ReferenceLoopHandling属性为ReferenceLoopHandling.Ignore,如下所示:

var stringObject = JsonConvert.SerializeObject(value, new JsonSerializerSettings()
{
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});

这样Json.NET检测到循环引用时,就会停止序列化操作,忽略对象的循环引用属性

 

c – 如何使用std :: shared_ptr检测或避免循环引用?

c – 如何使用std :: shared_ptr检测或避免循环引用?

我知道有一个weak_ptr来打破这个循环,但是在发现问题之后,这是一个修复.是否有可用于检测或避免循环引用的模式或工具?

解决方法

我会强烈反映sellibitze所说的内容,并重新考虑设计.如果你真正拥有的是单向所有权而只是观察相反的方向,则考虑weak_ptr.这允许您检查对象是否处于活动状态,但不能仅仅因为您有一个指向它的指针而使对象保持活动状态.

delphi – 如何避免循环单元参考?

delphi – 如何避免循环单元参考?

想象下面两种棋牌游戏:
TChessBoard = class
private
  FBoard : array [1..8,1..8] of TChesspiece;
...
end;

TChesspiece = class abstract
public
   procedure GetMoveTargets (BoardPos : TPoint; Board : TChessBoard; MoveTargetList : TList <TPoint>);
...
end;

我想让这两个类在两个单独的单元ChessBoard.pas和Chesspiece.pas中定义.

如何避免我遇到的圆形单元参考(在其他单元的界面部分需要每个单元)?

解决方法

将定义TChesspiece的单位更改为如下所示:
TYPE
  tBaseChessBoard = class;

  TChesspiece = class
    procedure GetMoveTargets (BoardPos : TPoint; Board : TBaseChessBoard; ...    
  ...
  end;

然后修改定义TChessBoard的单元如下所示:

USES
  unit_containing_tBaseChessboard;

TYPE
  TChessBoard = class(tBaseChessBoard)
  private
    FBoard : array [1..8,1..8] of TChesspiece;
  ...
  end;

这样就可以将具体的实例传递给棋子,而无需担心循环引用.由于董事会私人使用Tchesspieces,所以在Tchesspiece声明之前,它并不一定存在,就像持有人一样.当然,tChesspiece必须知道的任何状态变量都应该放在tBaseChessBoard中,两者都可以使用.

delphi – 我有两个单元,每个单元中有一个需要彼此运行的类.如何避免循环引用?

delphi – 我有两个单元,每个单元中有一个需要彼此运行的类.如何避免循环引用?

我有2个类,ClassA和ClassB,每个类都在它们自己的单独单元UnitA和UnitB中.

UnitA使用UnitB.这允许ClassA调用ClassB的构造函数.但是,ClassB的部分功能需要使用ClassA的方法.我无法使UnitB使用UnitA,否则会导致循环引用.在允许ClassB从UnitB中访问ClassA的方法时,我还有什么办法?

解决方法

这很大程度上取决于两个类如何相互使用.如果一个类在实现中使用另一个类而不是接口,那么您可以将uses子句中的该单元从接口部分向下移动到实现部分.

这可以解决这个问题:

UnitA;

interface

uses
  Classes,UnitB;

type
  TClassA = class(TObject)
  end;

...

.

UnitB;

interface

uses
  Classes;

type
  TClassB = class(TObject)
  end;

implementation

uses
  UnitA;

...

但是,如果两个类的接口彼此依赖,那么您别无选择,只能将两个类放在同一个单元中(并使用前向声明).

UnitA;

interface

uses
  Classes;

type
  TClassA = class;
  TClassB = class;


  TClassA = class(TObject)
  end;

  TClassB = class(TObject)
  end;

...

在极少数情况下,您甚至可以将整个类定义向下移动到实现.如果您需要在其他地方实际使用该类,那么这将没有用.

UnitB;

interface

implementation

uses
  Classes,UnitA;

type
  TClassB = class(TObject)
  end;

...

根据复杂性,通常的做法是将共同的代码放在它自己的独立单元中.例如常量,记录数组类型,全局变量等.这个公共单元不得使用这些单元中的任何其他单元.

EF 4.1-代码优先-JSON循环引用序列化错误

EF 4.1-代码优先-JSON循环引用序列化错误

尽管据我所知我没有任何循环引用,但是我遇到了循环引用序列化错误。我正在从数据库中检索一组订单,并将它们作为JSON发送到客户端。所有代码如下所示。

这是错误:

错误

序列化类型为’System.Data.Entity.DynamicProxies.Order_83CECF2AA4DE38232F9077D4B26941AB96BC61230419EA8AC42C9100E6072812’的对象时,检测到循环引用。说明:执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪,以获取有关错误及其在代码中起源的更多信息。

异常详细信息:System.InvalidOperationException:序列化类型为’System.Data.Entity.DynamicProxies.Order_83CECF2AA4DE38232F9077D4B26941AB96BC61230419EA8AC42C9100E6072812’的对象时,检测到循环引用。

源错误:

当前Web请求的执行期间生成了未处理的异常。可以使用下面的异常堆栈跟踪来标识有关异常的来源和位置的信息。

我的课程如下:

订购

public class Order{    [Key]    public int OrderId { get; set; }    public int PatientId { get; set; }    public virtual Patient Patient { get; set; }    public int CertificationPeriodId { get; set; }    public virtual CertificationPeriod CertificationPeriod { get; set; }    public int AgencyId { get; set; }    public virtual Agency Agency { get; set; }    public int PrimaryDiagnosisId { get; set; }    public virtual Diagnosis PrimaryDiagnosis { get; set; }    public int ApprovalStatusId { get; set; }    public virtual OrderApprovalStatus ApprovalStatus { get; set; }    public int ApproverId { get; set; }    public virtual User Approver { get; set; }    public int SubmitterId { get; set; }    public virtual User Submitter { get; set; }    public DateTime ApprovalDate { get; set; }    public DateTime SubmittedDate { get; set; }    public Boolean IsDeprecated { get; set; }}

患者

public class Patient{    [Key]    public int PatientId { get; set; }    public string FirstName { get; set; }    public string LastName { get; set; }    public string MiddleInitial { get; set; }    public bool IsMale;    public DateTime DateOfBirth { get; set; }    public int PatientAddressId { get; set; }    public Address PatientAddress { get; set; }    public bool IsDeprecated { get; set; }}

认证期限

public class CertificationPeriod{    [Key]    public int CertificationPeriodId { get; set; }    public DateTime startDate { get; set; }    public DateTime endDate { get; set; }    public bool isDeprecated { get; set; }}

机构

public class Agency{    [Key]    public int AgencyId { get; set; }    public string Name { get; set; }    public int PatientAddressId { get; set; }    public virtual Address Address { get; set; }}

诊断

public class Diagnosis{    [Key]    public int DiagnosisId { get; set; }    public string Icd9Code { get; set; }    public string Description { get; set; }    public DateTime DateOfDiagnosis { get; set; }    public string Onset { get; set; }    public string Details { get; set; }}

OrderApprovalStatus

public class OrderApprovalStatus{    [Key]    public int OrderApprovalStatusId { get; set; }    public string Status { get; set; }}

用户

public class User{    [Key]    public int UserId { get; set; }    public string Login { get; set; }    public string FirstName { get; set; }    public string LastName { get; set; }    public string NPI { get; set; }    public string Email { get; set; }}

注意:地址类别是编辑过程中的新添加

地址

public class Address{    [Key]    public int AddressId { get; set; }    public string StreetAddress { get; set; }    public string City { get; set; }    public string State { get; set; }    public string Zip { get; set; }    public string Phone { get; set; }    public string Title { get; set; }    public string Label { get; set; }}

执行序列化的代码在这里:

摘自OrderController

    public ActionResult GetAll()    {        return Json(ppEFContext.Orders, JsonRequestBehavior.AllowGet);    }

谢谢

答案1

小编典典

您可以尝试virtual从所有导航属性中删除关键字以禁用延迟加载和代理创建,然后使用快速加载来显式加载所需的对象图:

public ActionResult GetAll(){    return Json(ppEFContext.Orders                           .Include(o => o.Patient)                           .Include(o => o.Patient.PatientAddress)                           .Include(o => o.CertificationPeriod)                           .Include(o => o.Agency)                           .Include(o => o.Agency.Address)                           .Include(o => o.PrimaryDiagnosis)                           .Include(o => o.ApprovalStatus)                           .Include(o => o.Approver)                           .Include(o => o.Submitter),        JsonRequestBehavior.AllowGet);}

参考您以前的文章,您的应用程序似乎也不依赖于延迟加载,因为您在那里引入了虚拟属性来延迟加载对象图,这可能会导致序列化麻烦。

编辑

不必virtual从导航属性中删除关键字(这将使模型完全无法进行延迟加载)。在代理受干扰的特定情况下(例如序列化),禁用代理创建(也将禁用延迟加载)就足够了:

ppEFContext.Configuration.ProxyCreationEnabled = false;

这仅对特定的上下文实例禁用代理创建ppEFContext

(我刚刚看过,@ WillC在这里已经提到过。请对此答案表示支持。)

我们今天的关于Json.NET如何避免循环引用json 循环引用的分享就到这里,谢谢您的阅读,如果想了解更多关于c – 如何使用std :: shared_ptr检测或避免循环引用?、delphi – 如何避免循环单元参考?、delphi – 我有两个单元,每个单元中有一个需要彼此运行的类.如何避免循环引用?、EF 4.1-代码优先-JSON循环引用序列化错误的相关信息,可以在本站进行搜索。

本文标签: