c# - ef4 导致 Web 服务中的循环引用

标签 c# .net web-services entity-framework serialization

我有一个 Reason 对象:

public class Reason
{
    public virtual long Id { get; set; }
    public virtual string Name { get; set; }
    public virtual Company Company {get;set;}
}

我正在使用 Entity Framework 4,公司是公司的导航属性。
我还使用网络服务来将数据返回给客户端。
我有返回原因的网络方法:

  [WebMethod]
    public Reason[] GetCallReasons()
    {
        IReasonRepository rep =
            ObjectFactory.GetInstance<IReasonRepository>();
        return rep.GetReasonsList().ToArray();
    }

由于 ef4,我在执行 web 方法时遇到以下异常:

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

问题出现是因为 ef4 添加了无法序列化的属性: Image of the watch panel on rep.GetReasonsList().ToArray()

为了解决这个问题并消除错误,我可以通过不将其设为虚拟或删除导航属性来禁用导航属性。但我需要它并想使用延迟加载功能。

我也可以为 Reason 编写特定的序列化程序,但我在我的 Web 服务中使用了很多类,并且为所有这些类编写一个序列化程序是一项大量的工作。

我该如何解决这个异常?..

最佳答案

您的问题有多种解决方案,它们实际上取决于您使用的服务类型和序列化类型:

  • 干净的方法是使用 DTO(数据传输对象),正如 @Mikael 已经建议的那样。 DTO 是一个特殊的对象,它只传输你所需要的,仅此而已。您可以简单地创建不包含循环引用的 DTO 并使用 AutoMapper在实体和 DTO 之间映射,反之亦然。为@Mikael +1,因为他是第一个提到这一点的人。

所有其他方法都基于 @Haz 建议的 tweeking 序列化:

  • WCF 和 DataContractSerializer:使用 DataContract[IsReference=true] 显式标记您的实体,使用 [DataMember] 属性显式标记所有属性。这将允许您使用循环引用。如果您使用 T4 模板生成实体,则必须对其进行修改以添加这些属性。
  • WCF 和 DataContractSerializer:隐式序列化。使用 [IgnoreDataMember] 属性标记一个相关的导航属性,这样属性就不会被序列化。
  • XmlSerializer:用[XmlIgnore]属性标记一个相关的导航属性
  • 其他序列化:使用 [NonSerialized] 标记一个相关的导航属性(+1,因为他是第一个提到这个的)用于普通序列化或 [ScriptIgnore]用于一些 JSON 相关的序列化。

关于c# - ef4 导致 Web 服务中的循环引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5762135/

相关文章:

html - 我可以制作不可下载的视频流吗(通过使用代码中的技巧)

java - Web 服务还是 Web 应用程序?

c# - CollectionView.Refresh不过滤

javascript - SignalR 拒绝连接到 [url],因为它违反了以下内容安全策略指令

c# - 删除 DataGridView 中两个单元格之间的行分隔符

.net - NLog 中的 appendTo 和 writeTo 有什么区别?

c# - 使用整数调用 DateTime.AddDays 是否始终保持时间不变?

java - 检测 Web 服务中的客户端断开连接

c# - 检查文本框中是否包含值 'abc' 而不是 'abc aze'

c# - 将管道参数发送到 C# 应用程序