2

JSON asp.net 3.5SP1 WebService (WCF ではなく、scriptservice属性を持つ従来の asp.net WebService) からオブジェクトを返そうとすると、「タイプ '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
  • インターフェイスの実装に使用されるため、読み取り専用プロパティを保持したいと思います。
  • 「IsReference:=True」属性を Bound クラスに追加しても、何も変わりません。
  • DataContractJsonSerializer (この例のように、webservice のコンテキスト外: link text ) を使用すると、機能し、正しい JSON が得られます。
  • 「Bds」読み取り専用プロパティを削除すると機能します!!

理由がわかりません!これは読み取り専用のプロパティであり、DataMember 属性がなく、IgnoreDatamember 属性があり、シリアル化することは想定されていません。

「Bds」プロパティを保持し、循環参照例外を取り除く方法は?

ありがとう !

4

2 に答える 2

1

これが機能する例です(C#の場合は申し訳ありません)

  1. 定義されたクラス:

    [DataContract(Namespace = "Geo")]
    public class Bound
    {
        [IgnoreDataMember]
        public Bound { get { return this; } }
    
    
       [DataMember]
       public string Name { get; set; }
    }
    
  2. 作成されたサービス インターフェイス (および実装)

    [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" };
        }
    }
    
  3. 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>
    
  4. 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 で処理されたテスト オブジェクトを受け取りました。

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

PS: WebInvokeAttribute はSystem.ServiceModel.Web.dllアセンブリにあります。

于 2010-12-01T20:55:41.220 に答える
0

Bound 型のプロパティへの参照を持つクラス Bound であるため、循環参照を取得しています。つまり、バインドされたオブジェクトの無限の供給です。

IgnoreDataMember が正しく機能しない理由がわかりません。もう少し時間をかけて、アイデアがあれば回答を更新します。

于 2010-12-01T19:14:01.317 に答える