Complex data types in WCF?
Asked Answered
A

14

21

I've run into a problem trying to return an object that holds a collection of childobjects that again can hold a collection of grandchild objects. I get an error, 'connection forcibly closed by host'.

Is there any way to make this work? I currently have a structure resembling this:

pseudo code:

Person:
IEnumerable<Order>

Order:
IEnumerable<OrderLine>

All three objects have the DataContract attribute and all public properties i want exposed (including the IEnumerable's) have the DataMember attribute.

I have multiple OperationContract's on my service and all the methods returning a single object OR an IEnumerable of an object works perfectly. It's only when i try to nest IEnumerable that it turns bad. Also in my client service reference i picked the generic list as my collection type. I just want to emphasize, only one of my operations/methods fail with this error - the rest of them work perfectly.

EDIT (more detailed error description):

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

I tried looking for logs but i can't find any... also i'm using a WSHttpBinding and an http endpoint.

Anchylose answered 15/10, 2008 at 8:31 Comment(3)
Is there something in your objects that is not serializing correctly?Olvera
I don't know. I was thinking perhaps a nested IEnumberable<T> might not get serialized? But how do i find out? I can debug all the way to the return of the actual OperationContract and everything is fine, but the transport seems to go wrong. I have no Serialize attribute but instead use [DataMember]Seldom
i'm facing the same error as you.. my classes are also defined with enum properties, but i am not seeing this as an issue anywhere.. enums should be fine.. and what do you mean by setting default value? they're value types so they always have a default value. i will try removing enum properties and see if that fixes it.. here is some info on supported data contract classes msdn.microsoft.com/en-us/library/ms731923.aspxSteward
R
37

As a note, you need to learn how to use the WCF logging utilities:

Logging info.

Config Editor (makes it a snap to setup).

Trace viewer. Totally awesome. Allows multiple services (client and server) to trace and can join them and help you analyse all the details. Lets you get to the root of issues really fast. (Cause when there's a server WCF error, the client is unlikely to get useful data out.)

Rubirubia answered 20/10, 2008 at 4:3 Comment(7)
Where can I find the trace viewer app, MS documentation talks about it but no reference on how to get started with it?Foote
JL, it's installed with Windows SDKCrumpler
+1 for the Trace Viewer...it really is an awesome tool! Just solved an issue for me that I'd been stewing over since yesterday.Talebearer
trace viewer = finally i don't have to assume a productivity penalty when i'm writing WCF appsQuid
I didn't know about Config Editor or Trace Viewer. They just saved me a huge headache. Thanks!Torsion
Now I know why so many upvote to this suggestion. For any WCF user, when you get ambiguous error like "An existing connection was forcibly closed..." , SvcTraceViewer is life saverChamorro
Yes, Trace Viewer is your very good friend when troubleshooting obscure WCF errorsDigitate
A
11

Ok i finally found the real problem in my case. It seems exposing enums is not the greatest thing in the world. I either have to set a default value on them, or instead expose the property as an int or whatever integer-type my enum is based on.

Thanks for helping, you had no way of knowing this - i found the enums on the 3rd level in my structure and systematicly removing datamembers one by one was the way i found out. It seems i'm not the only one who ran into this problem - this guy obviously had similar problems :)

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

Anchylose answered 15/10, 2008 at 11:12 Comment(0)
F
10

If you are working with WCF+(EF+POCO) then try setting,

ObjectContext.ContextOptions.LazyLoadingEnabled = false;
ObjectContext.ContextOptions.ProxyCreationEnabled = false;
Federico answered 29/10, 2010 at 8:23 Comment(2)
Thank you very much. You saved me from shooting myself!Agape
Or use AutoMapper, in which case you avoid solving just the symptoms.Henshaw
P
3

Add this line into <system.web/>:

<httpRuntime maxRequestLength="102400" executionTimeout="3600" />
Premedical answered 19/3, 2010 at 2:57 Comment(0)
S
3

Enums get a DataContract attribute, like any class would, but the enum values aren't supposed to have DataMember attributes on them.

Change them to EnumMember and you'll stop getting this inscrutable error.

Selima answered 9/1, 2011 at 9:22 Comment(0)
I
1

this is actually the same information as your first exception description. it would be interesing what the original cause for the socketexception was. it has to be some type of error in the service itself. can you locate where exactly whar exception happens?

i had similar errors when trying to return normal IEnumerables that were overwritten (they were marked as virtual) by NHibernate, and substitued with GenericPersistentBag, which is not serializable. have you marked your IEnumerable datamembers as virtual due to nhibernate or something similar? this could explain your error.

btw. wcf exceptions are often quite meaningless (which can be very frustrating when tracking down a bug ;)

Immeasurable answered 15/10, 2008 at 9:19 Comment(2)
That is all the exception information i can get. I get the same exception (if i include the stacktrace) when i debug through. We're using Linq2Sql but actually converting those object to lighter objects that only holds simple datatypes with the exception of these nested collections.Seldom
What i mean is - the objects that have DataContract on them are not part of anything else in the project - they are pretty much DTO's with the exception of holding collections of other "DTO's"Seldom
O
1

I have had the same problem too (.Net 3.5). Turns out my base class DataContract was missing a known type. It's unfortunate that the WCF error was not more descriptive.

Opuntia answered 22/1, 2010 at 3:2 Comment(0)
I
0

did you specify in your service behavior config? it seems like some information is missing in this stacktrace.

can you grab the exception at server side (e.g. in visual studio debug mode or with a logging library like log4net).

have you tried calling some other methods (simple helloworld() e.g.) on the same service to be sure that the service configuration itself works? this kind of exceptino could also indicate some serialization problems. what types do you want to send over the wire? do you use KnownType's somewhere?

Immeasurable answered 15/10, 2008 at 9:7 Comment(1)
I'm really glad for all the help i can get, so thanks for replying!, but please read my question again - only one of my methods fails with this error. Also about the exception i can post the full stacktrace but it just bloats the question? I'll post it in a reply then :)Seldom
A
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 
Anchylose answered 15/10, 2008 at 9:13 Comment(0)
E
0

I don't know why this can happen. but i also had similar problems.

I have changed my enums.remove the indexes(e.g. ASNOrder = 1, -> ASNOrder,),and no error occoured.

Eduction answered 28/11, 2008 at 1:56 Comment(0)
E
0

Don't return the literal IEnumerable in a contract, there is the famous WCF IEnumerable bug

Euphrosyne answered 22/1, 2010 at 3:7 Comment(0)
D
0

Yep, I had the same problem here and it was todo with returning objects that had enum values in it. Changed the DataMember to an int and everything statrted working.

Dinesen answered 23/4, 2010 at 14:47 Comment(0)
A
0

Try setting [OperationBehavior()] above your implementation of the interface method.

Albatross answered 13/8, 2010 at 14:0 Comment(0)
K
0

I've had this error when using 'yield return' to build up an enumeration of objects mapped to my DataContract type.

Calling ToList / ToArray on the yield results fixed the issue and the service call worked correctly.

Kellerman answered 25/10, 2010 at 16:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.