web-dev-qa-db-fra.com

Des types de données complexes dans WCF?

J'ai rencontré un problème en essayant de retourner un objet contenant une collection d'objets-enfants pouvant à nouveau contenir une collection d'objets petits-enfants. Je reçois une erreur 'Connexion forcée par l'hôte'.

Y a-t-il un moyen de faire fonctionner cela? J'ai actuellement une structure ressemblant à ceci:

pseudo code:

Person:
IEnumerable<Order>

Order:
IEnumerable<OrderLine>

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

J'ai plusieurs OperationContract sur mon service et toutes les méthodes renvoyant un seul objet OR un IEnumerable d'un objet fonctionnent parfaitement. Ce n'est que lorsque j'essaye d'imbriquer IEnumerable que ça tourne mal. Également dans ma référence de service client, j'ai choisi la liste générique comme type de collection. Je veux juste souligner que une seule de mes opérations/méthodes a échoué avec cette erreur - les autres fonctionnent parfaitement .

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

[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é de chercher des journaux mais je n'en trouve pas ... J'utilise également un WSHttpBinding et un point de terminaison http.

21

En guise de remarque, vous devez apprendre à utiliser les utilitaires de journalisation WCF:

Informations de journalisation.

Éditeur de configuration (facilite la configuration).

Visionneuse de traces. Absolument 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'accéder à la racine des problèmes très rapidement. (Parce qu'en cas d'erreur WCF sur le serveur, il est peu probable que le client obtienne des données utiles.)

38
MichaelGG

Ok, j'ai finalement trouvé le vrai problème dans mon cas. Il semble que dénoncer des enums n'est pas la plus grande chose au monde. Je dois soit leur attribuer une valeur par défaut, soit exposer la propriété sous la forme d'un int ou du type entier sur lequel mon enum est basé.

Merci de votre aide, vous n’avez aucun moyen de le savoir - j’ai trouvé les enums du 3ème niveau dans ma structure et le fait de supprimer systématiquement les membres de la base de données un par un était la méthode que j’ai découverte. Il semble que je ne suis pas le seul à avoir rencontré ce problème - ce gars-là avait évidemment des problèmes similaires :)

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

11

Si vous travaillez avec WCF + (EF + POCO), essayez de régler,

ObjectContext.ContextOptions.LazyLoadingEnabled = false;
ObjectContext.ContextOptions.ProxyCreationEnabled = false;
10
paragy

Les énumérations obtiennent un attribut DataContract, comme le ferait n'importe quelle classe, mais les valeurs enum ne sont pas supposées avoir l'attribut DataMember.

Remplacez-les par EnumMember et vous ne recevrez plus cette erreur impénétrable.

3
Brandon Roberson

Ajouter cette ligne dans <system.web/>:

<httpRuntime maxRequestLength="102400" executionTimeout="3600" />
3
Thoại Nguyễn

il s'agit en réalité des mêmes informations que votre description de première exception. il serait intéressant de savoir quelle était la cause initiale de l’exception socket. il doit y avoir une sorte d'erreur dans le service lui-même. pouvez-vous localiser exactement où une exception se produit?

j'avais des erreurs similaires lorsque j'essayais de renvoyer des IEnumerables normaux qui avaient été écrasés (marqués comme virtuels) par NHibernate et remplacés par GenericPersistentBag, qui n'était pas sérialisable. Avez-vous marqué vos membres IEnumerable comme virtuels en raison de nhibernate ou quelque chose de similaire? cela pourrait expliquer votre erreur.

btw. Les exceptions wcf n'ont souvent aucune signification (ce qui peut être très frustrant lors de la recherche d'un bogue;)

1

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

1
Kyle Lahnakoski

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

0
trkll

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

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

0
Rob Willis

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 ne s'est produite.

0
Greg Ho

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

pouvez-vous saisir l’exception côté serveur (par exemple, en mode débogage de Visual Studio ou avec une bibliothèque de journalisation telle que log4net).

avez-vous essayé d'appeler d'autres méthodes (simple helloworld (), par exemple) sur le même service pour vous assurer que la configuration du service lui-même fonctionne? Ce type d'exceptino pourrait également indiquer des problèmes de sérialisation. quels types voulez-vous envoyer sur le fil? utilisez-vous KnownType quelque part?

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 

Ne retournez pas la valeur littérale IEnumerable dans un contrat, il existe le fameux bogue WCF IEnumerable

0
Chris O

Oui, j'ai eu le même problème ici et c'était avec le retour d'objets renvoyant des valeurs enum. Changé DataMember en int et tout a commencé à fonctionner.

0
Tiny122