2008-10-15 11 views
21

Ich habe ein Problem beim Versuch, ein Objekt zurückgeben, die eine Auflistung von Childobjects, die wiederum eine Sammlung von Enkel-Objekten enthalten können zurückgegeben. Ich erhalte eine Fehlermeldung, die Verbindung wurde zwangsweise vom Host geschlossen.Komplexe Datentypen in WCF?

Gibt es eine Möglichkeit, dies zu funktionieren? Im Moment habe ich eine Struktur dieses ähnelt:

Pseudocode:

Person: 
IEnumerable<Order> 

Order: 
IEnumerable<OrderLine> 

Alle drei Objekte haben die Datacontract Attribut und alle öffentlichen Eigenschaften i (einschließlich des IEnumerable der) ausgesetzt wollen, müssen Sie die Datamember-Attribut.

Ich habe mehrere OperationContract auf meinem Dienst und alle Methoden, die ein einzelnes Objekt ODER ein IEnumerable eines Objekts zurückgeben, funktionieren perfekt. Nur wenn ich versuche IEnumerable zu verschachteln, wird es schlecht. Auch in meiner Client-Service-Referenz habe ich die generische Liste als meinen Sammlertyp ausgewählt. Ich möchte nur betonen, nur eine meiner Operationen/Methoden scheitern mit diesem Fehler - der Rest von ihnen funktioniert einwandfrei.

EDIT (ausführlichere Fehlerbeschreibung):

[SocketException (0x2746): An existing connection was forcibly closed by 
the remote host] 
[IOException: Unable to read data from the transport connection: 
An existing connection was forcibly closed by the remote host.] 
[WebException: The underlying connection was closed: An unexpected 
error occurred on a receive.] 
[CommunicationException: An error occurred while receiving the HTTP 
response to http://myservice.mydomain.dk/MyService.svc. This could 
be due to the service endpoint binding not using the HTTP protocol. 
This could also be due to an HTTP request context being aborted by 
the server (possibly due to the service shutting down). See server 
logs for more details.] 

habe ich versucht, für Protokolle aus, aber ich kann keine finden ... auch eine WSHttpBinding und einen HTTP-Endpunkt ich verwende.

+0

Gibt es etwas in Ihren Objekten, das nicht korrekt serialisiert? –

+0

Ich weiß es nicht. Ich dachte, ein verschachteltes IEnumberable könnte möglicherweise nicht serialisiert werden? Aber wie finde ich heraus? Ich kann den ganzen Weg bis zur Rückkehr des tatsächlichen OperationContract debuggen und alles ist in Ordnung, aber der Transport scheint falsch zu gehen. Ich habe kein Serialize-Attribut, aber stattdessen [DataMember] –

+0

Ich bin mit dem gleichen Fehler konfrontiert wie Sie .. meine Klassen sind auch mit Enum-Eigenschaften definiert, aber ich sehe das nicht als ein Problem überall .. enums sollte in Ordnung sein .. und was meinst du mit dem Standardwert? Sie sind Werttypen, so dass sie immer einen Standardwert haben.Ich werde versuchen Enum-Eigenschaften zu entfernen und sehen, ob das es behebt .. hier ist ein paar Informationen über unterstützte Daten-Vertragsklassen http://msdn.microsoft.com/en-us/library/ms731923.aspx –

Antwort

37

Als Hinweis, Sie müssen lernen, wie die WCF-Protokollierung Dienstprogramme verwenden:

Logging info.

Config Editor (macht es zu einem Kinderspiel).

Trace viewer. Total genial. Ermöglicht mehreren Services (Client und Server) die Verfolgung und kann ihnen beitreten und hilft Ihnen bei der Analyse aller Details. Damit kommst du schnell an die Wurzel von Problemen. (Wenn ein Server-WCF-Fehler auftritt, ist es unwahrscheinlich, dass der Client nützliche Daten ausgibt.)

+0

Wo finde ich die Trace Viewer App, MS Dokumentation spricht darüber, aber keine Referenz, wie man damit beginnt? –

+1

JL, es ist mit Windows SDK –

+0

+1 für den Trace Viewer installiert ... es ist wirklich ein tolles Werkzeug! Habe gerade ein Problem für mich gelöst, dass ich seit gestern dampfte. – w4ik

0

haben Sie in Ihrem Dienstverhalten config angegeben? Es scheint so, als ob in diesem Stacktrace einige Informationen fehlen.

können Sie die Ausnahme auf der Serverseite greifen (z. B. im Visual Studio-Debugmodus oder mit einer Protokollierungsbibliothek wie log4net).

Haben Sie versucht, einige andere Methoden (simple helloworld() z. B.) auf dem gleichen Dienst aufzurufen, um sicherzustellen, dass die Dienstkonfiguration selbst funktioniert? Diese Art von Exception könnte auch einige Serialisierungsprobleme anzeigen. Welche Typen möchten Sie über die Leitung senden? benutzt du KnownType irgendwo?

+0

Ich bin wirklich froh für alle die Hilfe, die ich bekommen kann, also danke für die Antwort !, aber bitte lesen Sie meine Frage noch einmal - nur eine meiner Methoden scheitert mit diesem Fehler. Auch über die Ausnahme kann ich den vollständigen Stacktrace posten, aber es nur die Frage aufbläht? Ich poste es in einer Antwort dann :) –

0
Server Error in '/' Application. 
-------------------------------------------------------------------------------- 

An existing connection was forcibly closed by the remote host 
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host 

Source Error: 

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. 

Stack Trace: 


[SocketException (0x2746): An existing connection was forcibly closed by the remote host] 
    System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) +93 
    System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) +119 

[IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.] 
    System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) +267 
    System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size) +25 
    System.Net.Connection.SyncRead(HttpWebRequest request, Boolean userRetrievedStream, Boolean probeRead) +306 

[WebException: The underlying connection was closed: An unexpected error occurred on a receive.] 
    System.Net.HttpWebRequest.GetResponse() +1532114 
    System.ServiceModel.Channels.HttpChannelRequest.WaitForReply(TimeSpan timeout) +40 

[CommunicationException: An error occurred while receiving the HTTP response to http://Zzzstrukturservice.xxx.dk/ZzzstrukturService.svc. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.] 
    System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +2668969 
    System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +717 
    xxx.Services.ZzzstrukturServiceClient.ZzzstrukturServiceProxy.IZzzstrukturService.GetMatrixSet(Int32 matrixSetId) +0 
    xxx.Services.ZzzstrukturServiceClient.ZzzstrukturRepository.GetMatrixSetById(Int32 matrixSetId) in f:\ccnet\work\xxx.Zzzstruktur\1. Presentation Layer\ZzzstrukturServiceClient\ZzzstrukturRepository.cs:90 
    xxx.yyy.yyyWeb.AnnoncePage.OnLoad(EventArgs e) in f:\ccnet\work\yyyV2\1. Presentation Layer\yyyWeb\Annonce.aspx.cs:40 
    System.Web.UI.Control.LoadRecursive() +47 
    System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1436 




-------------------------------------------------------------------------------- 
Version Information: Microsoft .NET Framework Version:2.0.50727.1433; ASP.NET Version:2.0.50727.1433 
1

Dies ist eigentlich die gleiche Information wie Ihre erste Beschreibung der Ausnahme. Es würde interessieren, was der ursprüngliche Grund für die Sockentexzeption war. Es muss eine Art von Fehler im Dienst selbst sein. Kannst du herausfinden wo genau was passiert?

Ich hatte ähnliche Fehler beim Versuch, normale IEnumerables zurückzugeben, die von NHibernate überschrieben wurden (sie wurden als virtuell gekennzeichnet), und ersetzt durch GenericPersistentBag, das nicht serialisierbar ist. haben Sie Ihre IEnumerable-Datenamaturen aufgrund von Nhibernate oder ähnlichem als virtuell markiert? Dies könnte Ihren Fehler erklären.

btw. WCF-Ausnahmen sind oft ziemlich bedeutungslos (was sehr frustrierend sein kann, wenn man einen Fehler aufspürt;)

+0

Das ist die ganze Ausnahme Information, die ich bekommen kann. Ich bekomme die gleiche Ausnahme (wenn ich den Stacktrace einschließe), wenn ich durch Debugging. Wir verwenden Linq2Sql, konvertieren diese Objekte jedoch tatsächlich in hellere Objekte, die nur einfache Datentypen enthalten, mit Ausnahme dieser verschachtelten Sammlungen. –

+0

Was ich meine ist - die Objekte, die DataContract auf sie haben, sind nicht Teil von etwas anderem in dem Projekt - sie sind so ziemlich DTO's mit der Ausnahme von Sammlungen von anderen "DTOs" –

11

Ok, ich habe endlich das wirkliche Problem in meinem Fall gefunden. Es scheint, dass das Aufdecken von Enums nicht das Größte auf der Welt ist. Ich muss entweder einen Standardwert für sie festlegen oder stattdessen die Eigenschaft als int oder einen beliebigen Integer-Typ angeben, auf dem meine enum basiert.

Danke, dass du geholfen hast, du konntest das nicht wissen - ich fand die Enums auf der dritten Ebene in meiner Struktur und das systematische Entfernen von Datenmembern nach dem anderen war die Art, wie ich es herausgefunden habe.Es scheint, ich bin nicht der einzige, der in dieses Problem lief - dieser Kerl offensichtlich hatte ähnliche Probleme :)

http://zianet.dk/blog/2007/11/24/serializing-enums-in-wcf/

0

Ich weiß nicht, warum das passieren kann. aber ich hatte auch ähnliche Probleme.

Ich habe meine enums.remove die Indizes geändert (z. B. ASNOrder = 1, -> ASNOrder,), und kein Fehler aufgetreten.

1

Ich hatte das gleiche Problem (. NET 3.5). Stellt sich heraus, dass meine Basisklasse DataContract einen bekannten Typ fehlte. Es ist bedauerlich, dass der WCF-Fehler nicht beschreibender war.

0

Sie die wörtliche IEnumerable in einem Vertrag nicht zurück, gibt es die berühmte WCF IEnumerable bug

3

Fügen Sie diese Zeile in <system.web/>:

<httpRuntime maxRequestLength="102400" executionTimeout="3600" /> 
+0

Gespeichert wurde mir. Vielen Dank! – wcm

0

Ja, ich hatte das gleiche Problem hier und es wurde todo mit Rückgabe von Objekten, die enum-Werte enthielten. Die DataMember wurde in einen int geändert und alles funktionierte.

0

Versuchen Sie [OperationBehavior()] über Ihre Implementierung der Schnittstellenmethode.

0

Ich hatte diesen Fehler bei der Verwendung von 'yield return', um eine Auflistung von Objekten zu erstellen, die meinem Typ DataContract zugeordnet sind.

Aufruf ToList/ToArray auf die Ausbeute Ergebnisse behoben das Problem und der Service-Aufruf funktionierte korrekt.

10

Wenn Sie mit WCF + (EF + POCO) arbeiten dann Einstellung versuchen,

ObjectContext.ContextOptions.LazyLoadingEnabled = false; 
ObjectContext.ContextOptions.ProxyCreationEnabled = false; 
+0

Vielen Dank. Du hast mich davor bewahrt, mich selbst zu erschießen! – Dragan

+0

Oder verwenden Sie "AutoMapper", in diesem Fall vermeiden Sie nur die Symptome zu lösen. –

3

Aufzählungen erhalten ein DataContract Attribut, wie jede Klasse würde, aber die ENUM-Werte sind nicht DataMember Attribute soll auf haben Sie.

Ändern Sie sie zu EnumMember und Sie werden aufhören, diesen unerforschlichen Fehler zu bekommen.

+0

Dieser hat den Trick gemacht: D –