2010-12-01 8 views
2

Wenn ein Objekt aus einer JSON asp.net 3.5SP1 WebService zurückzukehren versuchen (nicht WCF, klassische asp.net WebService mit Script Attribut), habe ich eine "eine kreisförmige Referenz detektiert wurde, während ein Objekt des Typs 'Geo.Bound' Serialisierung" Fehler, verursacht durch einen selbstverweis Read-only-Eigenschaft:Serialisierung Kreis Ausnahme verursacht durch sich selbst verweis Read-only Eigenschaft

Vereinfachtes Code:

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 
  • I Ich möchte die Read-Only-Eigenschaft beibehalten, da sie zum Implementieren einer Schnittstelle verwendet wird.
  • Das Hinzufügen eines Attributs "IsReference: = True" zur Bound-Klasse ändert nichts.
  • Wenn ich einen DataContractJsonSerializer verwende (außerhalb des Kontexts des Webservice, wie dieses Beispiel: link text), funktioniert es und ich habe einen korrekten JSON.
  • Wenn ich die "BDS" Read-only-Eigenschaft entfernen, funktioniert es !!

Ich verstehe nicht warum! Es handelt sich um eine schreibgeschützte Eigenschaft ohne ein DataMember-Attribut mit einem IgnoreDatamember-Attribut, das nicht serialisiert werden soll!

Wie behalten Sie die "Bds" -Eigenschaft, und entfernen Sie die zirkuläre Referenz Ausnahme?

Danke!

+1

Wie haben Sie WCF für die Arbeit mit DataContractJsonSerializer eingerichtet? Vielleicht hast du da einen Fehler gemacht? –

+0

Meine Frage war nicht klar, also habe ich es bearbeitet: es ist ein klassischer asp.net-Dienst (nicht WCF), der Test mit DataContractJsonSerializer war außerhalb des Kontexts eines Webservice. – PlageMan

Antwort

0

Sie erhalten den Zirkelverweis Weil es die Klasse Bound mit einem Verweis auf eine Eigenschaft des Typs Bound ist. Das bedeutet, es ist eine endlose Lieferung von gebundenen Objekten.

Nicht sicher, warum IgnoreDataMember nicht richtig funktioniert. Ich gebe das noch etwas Zeit und aktualisiere meine Antwort, wenn ich Ideen habe.

1

Hier ist beispielsweise die (sorry für C#) arbeitet

  1. definierte Klasse:

    [DataContract(Namespace = "Geo")] 
    public class Bound 
    { 
        [IgnoreDataMember] 
        public Bound { get { return this; } } 
    
    
        [DataMember] 
        public string Name { get; set; } 
    } 
    
  2. Erstellt Service Interface (und Implementierung)

    [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. Edited System .serviceModel Teil von app.config

    <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. Gestartet Diensthost in Program.cs

    using (var sh = new ServiceHost(typeof(Service1))) 
    { 
        sh.Open(); 
        Console.WriteLine("Opened"); 
        Console.ReadLine(); 
    } 
    

gestartetes Programm, geöffnet Browser, http://localhost:8732/Design_Time_Addresses/JsonSerializationTest/Service1/DoWork eingegeben und erhielt Json-ed Prüfobjekt:

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

PS: WebInvokeAttribute befindet sich in System.ServiceModel.Web.dll Assembly.

+0

Leider kann ich WCF in diesem Projekt nicht verwenden, aber zu wissen, dass es in WCF funktioniert, ist interessant ... – PlageMan

+0

Oh, Entschuldigung. Viel Glück mit klassischem ASP.NET.) –