2008-10-15 4 views
21

J'ai rencontré un problème en essayant de retourner un objet qui contient une collection de childobjects qui peuvent à nouveau contenir une collection d'objets petits-enfants. Je reçois une erreur, "connexion forcée fermée par l'hôte".Types de données complexes dans WCF?

Y at-il un moyen de faire ce travail? J'ai actuellement une structure qui ressemble à ceci:

code pseudo:

Person: 
IEnumerable<Order> 

Order: 
IEnumerable<OrderLine> 

Tous les trois objets ont l'attribut DataContract et toutes les propriétés publiques que je veux Exposed (y compris le IEnumerable de) ont l'attribut DataMember.

J'ai plusieurs OperationContract sur mon service et toutes les méthodes retournant un seul objet OU un IEnumerable d'un objet fonctionnent parfaitement. C'est seulement quand j'essaie d'imbriquer IEnumerable que ça tourne mal. Aussi dans ma référence de service client j'ai choisi la liste générique comme type de collection. Je veux juste souligner, seulement une de mes opérations/méthodes échouent avec cette erreur - le reste d'entre eux fonctionne parfaitement.

EDIT (description plus détaillée d'erreur):

[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.] 

J'ai essayé la recherche de journaux, mais je ne trouve pas ... Je suis aussi l'aide d'un WSHttpBinding et un point de terminaison http.

+0

Y a-t-il quelque chose dans vos objets qui n'est pas sérialisé correctement? –

+0

Je ne sais pas. Je pensais peut-être qu'un IEnumberable imbriqué pourrait ne pas être sérialisé? Mais comment puis-je savoir? Je peux déboguer jusqu'au retour de l'OperationContract et tout va bien, mais le transport semble aller mal. Je n'ai pas d'attribut Serialize mais utilise plutôt [DataMember] –

+0

Je suis confronté à la même erreur que vous .. mes classes sont également définies avec des propriétés enum, mais je ne vois pas cela comme un problème n'importe où .. enums devrait être bien .. et que voulez-vous dire en définissant la valeur par défaut? ils sont des types de valeur, donc ils ont toujours une valeur par défaut.Je vais essayer de supprimer les propriétés enum et voir si cela résout .. voici quelques informations sur les classes de contrat de données prises en charge http://msdn.microsoft.com/en-us/library/ms731923.aspx –

Répondre

37

Comme une note, vous devez apprendre à utiliser les services d'enregistrement de WCF:

Logging info.

Config Editor (facilite l'installation).

Trace viewer. Totalement génial. Permet à plusieurs services (client et serveur) de tracer et peut les joindre et vous aider à analyser tous les détails. Vous permet d'arriver à la racine des problèmes très rapidement. (Parce qu'il y a une erreur WCF du serveur, il est peu probable que le client obtienne des données utiles.)

+0

Où puis-je trouver l'application de visualisation de traces, MS la documentation en parle, mais aucune référence sur la façon de commencer avec elle? –

+1

JL, il est installé avec Windows SDK –

+0

+1 pour le Trace Viewer ... c'est vraiment un outil génial! Je viens juste de résoudre un problème pour moi que je remuais depuis hier. – w4ik

0

avez-vous spécifié dans votre configuration de comportement de service? il semble que certaines informations manquent dans cette pile.

pouvez-vous récupérer l'exception côté serveur (par exemple en mode Visual Studio Debug ou avec une bibliothèque de journalisation comme Log4net).

avez-vous essayé d'appeler d'autres méthodes (par exemple helloworld() par exemple) sur le même service pour vous assurer que la configuration du service elle-même fonctionne? ce genre d'exception peut également indiquer certains problèmes de sérialisation. Quels types voulez-vous envoyer sur le fil? utilisez-vous quelque part KnownType?

+0

Je suis vraiment heureux pour tous l'aide que je peux obtenir, alors merci d'avoir répondu !, mais s'il vous plaît relisez ma question - une seule de mes méthodes échoue avec cette erreur. Aussi à propos de l'exception je peux poster le full stacktrace mais cela ne fait que gonfler la question? Je vais le poster dans une réponse alors :) –

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

Ceci est en fait la même information que votre première description d'exception. il serait interesing ce que la cause originale pour le socketexception était. il doit y avoir un certain type d'erreur dans le service lui-même. pouvez-vous localiser où exactement l'exception de whar se produit? J'ai eu des erreurs similaires en essayant de retourner les IEnumerables normales qui ont été remplacées (elles ont été marquées comme virtuelles) par NHibernate, et remplacées par GenericPersistentBag, qui n'est pas sérialisable. avez-vous marqué vos datamembres IEnumerable comme virtuels en raison de nhibernate ou quelque chose de similaire? Cela pourrait expliquer votre erreur.

btw. les exceptions wcf sont souvent sans signification (ce qui peut être très frustrant lors de la recherche d'un bug;)

+0

C'est toutes les informations d'exception que je peux obtenir. J'obtiens la même exception (si j'inclus la stacktrace) quand je débogue. Nous utilisons Linq2Sql mais en fait convertissons ces objets en objets plus légers qui ne contiennent que des types de données simples à l'exception de ces collections imbriquées. –

+0

Ce que je veux dire est - les objets qui ont DataContract sur eux ne font partie d'aucune autre chose dans le projet - ils sont à peu près DTO à l'exception de détenir des collections d'autres "DTO" –

11

Ok, j'ai finalement trouvé le vrai problème dans mon cas. Il semble que l'exposition d'enums n'est pas la meilleure chose au monde. Je dois soit définir une valeur par défaut sur eux, soit exposer la propriété en tant qu'int ou quel type entier mon enum est basé. Merci pour votre aide, vous n'aviez aucun moyen de le savoir - j'ai trouvé les énumérations sur le 3ème niveau dans ma structure et en supprimant systématiquement les membres de données un par un était la façon dont j'ai découvert.Il semble que je ne suis pas le seul qui a couru dans ce problème - ce gars-là avait évidemment des problèmes similaires :)

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

0

Je ne sais pas pourquoi cela peut arriver. mais j'ai aussi eu des problèmes similaires.

J'ai changé mes enums.remove les index (par exemple ASNOrder = 1, -> ASNOrder,), et aucune erreur n'est survenue.

1

J'ai eu le même problème aussi (.Net 3.5). Il s'avère que ma classe de base DataContract manquait un type connu. Il est regrettable que l'erreur WCF ne soit pas plus descriptive.

0

Ne retournez pas le IEnumerable littéral dans un contrat, il y a le célèbre WCF IEnumerable bug

3

Ajouter cette ligne dans <system.web/>:

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

m'a sauvé. Merci! – wcm

0

Eh oui, j'ai eu le même problème ici et il a été todo avec renvoyer des objets contenant des valeurs enum. Changé le DataMember à un int et tout travail statrted.

0

Essayez de définir [OperationBehavior()] au-dessus de votre implémentation de la méthode d'interface.

0

J'ai rencontré cette erreur lors de l'utilisation de 'yield return' pour créer une énumération d'objets mappés à mon type DataContract.

L'appel ToList/ToArray sur les résultats de rendement a corrigé le problème et l'appel de service a fonctionné correctement.

10

Si vous travaillez avec WCF + (EF + POCO) puis essayez de définir,

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

Merci beaucoup. Tu m'as sauvé de me tirer dessus! – Dragan

+0

Ou utilisez 'AutoMapper', auquel cas vous évitez de résoudre seulement les symptômes. –

3

énumérations obtenir un attribut DataContract, comme toute la classe serait, mais les valeurs enum ne sont pas censés avoir DataMember attributs sur leur.

Modifiez-les en EnumMember et vous arrêterez d'obtenir cette erreur inscrutable.

+0

Celui-ci a fait l'affaire: D –