将实体框架对象转换为 JSON 对象

发布于 2024-12-11 17:46:32 字数 667 浏览 0 评论 0原文

我试图让通用处理程序根据我的实体类型 SYSTEM_AUDIT_SHEET 发布 JSONJ 对象:

SYSTEM_AUDIT_SHEET sheet = ctx.SYSTEM_AUDIT_SHEET
                              .Where(s => s.SYSTEM_KEY == system_key_dec)
                              .Select(s => s)
                              .OrderByDescending(s => s.AUDIT_SHEET_VERSION)
                              .First();

HttpContext.Current.Response.Write(serializer.Serialize(sheet));

但出现以下错误:

序列化类型的对象时检测到循环引用 'System.Data.Entity.DynamicProxies.SYSTEM_AUDIT_SHEET_521A7B786A51FC0F83641182DD72C8DFE6C082418D30BBB977B403409A74CE17'。

为什么我无法将实体转换为 JSON?

I'm trying to make a generic handler post a JSONJ object based on my entity type SYSTEM_AUDIT_SHEET:

SYSTEM_AUDIT_SHEET sheet = ctx.SYSTEM_AUDIT_SHEET
                              .Where(s => s.SYSTEM_KEY == system_key_dec)
                              .Select(s => s)
                              .OrderByDescending(s => s.AUDIT_SHEET_VERSION)
                              .First();

HttpContext.Current.Response.Write(serializer.Serialize(sheet));

But I get the following error:

A circular reference was detected while serializing an object of type
'System.Data.Entity.DynamicProxies.SYSTEM_AUDIT_SHEET_521A7B786A51FC0F83641182DD72C8DFE6C082418D30BBB977B403409A74CE17'.

Why can't I convert the entity to JSON?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

墨小墨 2024-12-18 17:46:32

您无法将对象转换为引用自身的 json,因为这会创建无限长的 json 字符串。

例如,以下伪代码不起作用,因为它设置了循环引用(Dog >> Bone >> Dog ...):

class Dog {
    private Bone myBone;
    public Dog() {
        myBone = new Bone(this);
    }
}

class Bone {
    private Dog buriedBy;
    public Bone(Dog d) {
        buriedBy = d;
    }
}

通过谷歌搜索“json循环引用”似乎有一些很好的解决方案。请参阅顶部的两个堆栈溢出链接。

You cannot convert objects to json that reference themselves as this would create an infinitely long json string.

For example, the following pseudo-code wouldn't work because it sets up a circular reference (Dog >> Bone >> Dog...):

class Dog {
    private Bone myBone;
    public Dog() {
        myBone = new Bone(this);
    }
}

class Bone {
    private Dog buriedBy;
    public Bone(Dog d) {
        buriedBy = d;
    }
}

There seem to be some good solutions by googling 'json circular reference'. See the top two stack overflow links.

月棠 2024-12-18 17:46:32

问题可能是您的 SYSTEM_AUDIT_SHEET 包含引用 SYSTEM_AUDIT_SHEET 类型实例的属性,或者包含指向具有指向 SYSTEM_AUDIT_SHEET 指针的对象的属性/code> 实例。序列化这样的指针循环将导致序列化过程永远不会结束。

在进行序列化之前,您需要将 SYSTEM_AUDIT_SHEET 转换为不(直接或间接)引用自身的类型。您可以创建一个全新的类型并编写代码来实例化 SYSTEM_AUDIT_SHEET 中的此类类型 (AutoMapper< /a> 在这里可能会派上用场)。但是,我倾向于发现,在大多数情况下,使用匿名类型更容易:

SYSTEM_AUDIT_SHEET sheet = /*some sheet*/
var json = new {
  sheet.Id,
  sheet.RevisionNumber,
  sheet.Title
};
return serializer.Serialize(json);

编辑

如果您想使用 AutoMapper 并假设您的工作表看起来像

class SYSTEM_AUDIT_SHEET 
{
    public int Id { get; set; }
    public SYSTEM_AUDIT_SHEET SomeOtherAuditSheet { get;set;}
    public string Title { get;set;}
}

您可以创建一个类似的类型,

class JSON_SYSTEM_AUDIT_SHEET
{
    public int Id { get; set; }
    public int SomeOtherAuditSheetsId { get;set;}
    public string Title { get;set;}
}

当您应用程序启动(例如,在 Application_Start 中)时,您配置 AutoMapper:

AutoMapper.Mapper.CreateMap<SYSTEM_AUDIT_SHEET, JSON_SYSTEM_AUDIT_SHEET>()
  .ForMember(dest => dest.SomeOtherAuditSheetsId, opt => opt.MapFrom(src => src.SomeOtherAuditSheet.Id));

IdTitle 属性将直接从 SYSTEM_AUDIT_SHEET 映射到JSON_SYSTEM_AUDIT_SHEET 因为它们在两种类型中具有相同的名称。属性 SomeOtherAuditSheetsId 需要特殊配置,因为源类型上没有具有该确切名称的属性。

当您想要将 SYSTEM_AUDIT_SHEET 转换为 JSON_SYSTEM_AUDIT_SHEET 时,您可以执行以下操作:

return AutoMapper.Mapper.Map<SYSTEM_AUDIT_SHEET , JSON_SYSTEM_AUDIT_SHEET >(sheet);

您可能需要查看AutoMapper 的展平功能< /a>.

希望这有帮助。

The problem is probably that your SYSTEM_AUDIT_SHEET either contains a property that references instances of type SYSTEM_AUDIT_SHEET, or it contains a property that points to objects that have pointers to SYSTEM_AUDIT_SHEET instances. Serializing such a circle of pointers would result in a serialization process that would never end.

You will need to transform your SYSTEM_AUDIT_SHEET to a type that does not (directly or indirectly) reference itself before doing the serialization. You can create a brand new type and write code to instantiate such a type from your SYSTEM_AUDIT_SHEET (AutoMapper might come in handy here). However, I tend to find that in most cases it is easier to just use an anonymous type:

SYSTEM_AUDIT_SHEET sheet = /*some sheet*/
var json = new {
  sheet.Id,
  sheet.RevisionNumber,
  sheet.Title
};
return serializer.Serialize(json);

EDIT

If you want to use AutoMapper and assuming that your sheet looks something like

class SYSTEM_AUDIT_SHEET 
{
    public int Id { get; set; }
    public SYSTEM_AUDIT_SHEET SomeOtherAuditSheet { get;set;}
    public string Title { get;set;}
}

you could create a type like

class JSON_SYSTEM_AUDIT_SHEET
{
    public int Id { get; set; }
    public int SomeOtherAuditSheetsId { get;set;}
    public string Title { get;set;}
}

When your application starts (say, in Application_Start) you configure AutoMapper:

AutoMapper.Mapper.CreateMap<SYSTEM_AUDIT_SHEET, JSON_SYSTEM_AUDIT_SHEET>()
  .ForMember(dest => dest.SomeOtherAuditSheetsId, opt => opt.MapFrom(src => src.SomeOtherAuditSheet.Id));

The Id and Title properties will be mapped directly across from SYSTEM_AUDIT_SHEET to JSON_SYSTEM_AUDIT_SHEET because they have the same names in both types. The property SomeOtherAuditSheetsId needs special configuration, because there is no property with that exact name on the source type.

When you want to convert SYSTEM_AUDIT_SHEET to JSON_SYSTEM_AUDIT_SHEET you do:

return AutoMapper.Mapper.Map<SYSTEM_AUDIT_SHEET , JSON_SYSTEM_AUDIT_SHEET >(sheet);

You may want to have a look at AutoMapper's flattening features.

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文