首页 文章

序列化由自引用只读属性引起的循环异常

提问于
浏览
2

当试图从JSON asp.net 3.5SP1 WebService(不是WCF,带有scriptservice属性的经典asp.net WebService)返回一个对象时,我有一个 "A circular reference was detected while serializing an object of type 'Geo.Bound'" 错误,由自引用只读属性引起:

简化代码:

Namespace Geo
<DataContract(Namespace:="Geo", IsReference:=True)> _
Public Class Bound

 <DataMember(Name:="sw", IsRequired:=False)> _
 Public SouthWestCoord As Double


 Public Sub New()
  SouthWestCoord = 1.5#
 End Sub

 <IgnoreDataMember()> _
 Public ReadOnly Property Bds() As Bound
  Get
   Return Me
  End Get
 End Property

End Class
End Namespace
  • 我想保留Read-Only属性,因为它用于实现接口 .

  • 向Bound类添加"IsReference:=True"属性不会改变任何内容 .

  • 如果我使用DataContractJsonSerializer(在webservice的上下文之外,就像这个例子:link text),它可以工作,我有一个正确的JSON .

  • 如果删除"Bds"只读属性,它可以正常工作!!

我不明白为什么!它是一个readonly属性,没有DataMember属性,具有IgnoreDatamember属性,它不应该被序列化!

如何保留“Bds”属性,并摆脱循环引用异常?

谢谢 !

2 回答

  • 0

    这是一个例子,有效(抱歉C#)

    • 定义的类:
    [DataContract(Namespace = "Geo")]
    public class Bound
    {
        [IgnoreDataMember]
        public Bound { get { return this; } }
    
    
       [DataMember]
       public string Name { get; set; }
    }
    
    • 创建服务接口(和实现)
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json)]
        Bound DoWork();
    }
    
    
    public class Service1 : IService1
    {
        public Bound DoWork()
        {
            return new Bound { Name = "Test Name" };
        }
    }
    
    • 编辑了app.config的system.serviceModel部分
    <behaviors>
      <endpointBehaviors>
        <behavior name="endBeh">
          <enableWebScript/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>
      <service name="JsonSerializationTest.Service1">
        <endpoint address="" binding="webHttpBinding" behaviorConfiguration="endBeh" contract="JsonSerializationTest.IService1" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8732/Design_Time_Addresses/JsonSerializationTest/Service1/"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    
    • 在Program.cs中启动了服务主机
    using (var sh = new ServiceHost(typeof(Service1)))
    {
        sh.Open();
        Console.WriteLine("Opened");
        Console.ReadLine();
    }
    

    启动程序,打开浏览器,输入http://localhost:8732/Design_Time_Addresses/JsonSerializationTest/Service1/DoWork并收到Json-ed测试对象:

    {"d":{"__type":"Bound:Geo","Name":"Test Name"}}
    

    PS:WebInvokeAttribute位于System.ServiceModel.Web.dll程序集中 .

  • 1

    您正在获取循环引用因为它's the class Bound with a reference to a property of type Bound. That means it'是一个绑定对象的供应 .

    不确定为什么IgnoreDataMember无法正常工作 . 如果我有任何想法,我会给这个更多的时间并更新我的答案 .

相关问题