views:

465

answers:

2

Every time my WCF Host application pool starts, the client making the first WCF call to it always throws "System.Xml.XmlException: There are multiple root elements" All subsequent calls work perfectly.

This exception happens on the consumer/client side of the WCF request. I've tested this for both a full WCF client and a Silverlight client. It's using basicHttpBinding, no security, and aspnetCompatabilityMode = true

It wouldn't be a big deal if the app pool stayed alive, but with the lack of activity, it shuts down and the error happens again when it starts back up.

I should also mention that the app pool sometimes starts from a non-WCF request to another page. But still the first time WCF is called, it still throws this exception on the client side.

Has anyone seen this? I can provide more details if necessary.

Thanks

A: 

It sounds to me like a serialization issue. I would investigate how you build your DataContracts -- you are using DataContracts and not the XML serialization attributes, right?

Edit: Based on our comments, I'm going to give a recommendation for your refactoring:

[DataContract] 
public class ImageEffectExcludeParamRequest
{ 
    [DataMember] 
    public string ImageID { get; set; } 

    [DataMember] 
    public int EffectID { get; set; } 

    [DataMember]
    public ResponseInfo AdditionalInfo { get; set; }
}


[DataContract] 
public class ResponseInfo 
{ 
    [DataMember] 
    public Enums.ServiceResponse.Status Status { get; set; } 

    [DataMember] 
    public string Message { get; set; } 
}

Using composition rather than inheritance should solve your problem.

Randolpho
Right, They're all simple classes with DataContract,DataMember attributes only. Hmm... some operations have parameters that include entities with both Serializable and DataContract for other reasons. This one I've been testing does not though. The response value is an inherited object. [DataContract] public class ImageEffectExcludeParamRequest : RequestBase { [DataMember] public string ImageID { get; set; } [DataMember] public int EffectID { get; set; } }
Nathan
[DataContract] public abstract class ResponseBase { [DataMember] public Enums.ServiceResponse.Status Status { get; set; } [DataMember] public string Message { get; set; } public ResponseBase() { this.Status = Status.NotSet; this.Message = null; } }
Nathan
I would refactor; don't bother with ResponseBase for your data contracts. Instead, duplicate what you must or encapsulate the information in a separate field.
Randolpho
I'm digging through it now, and I realize it does make its first call (before the one I mentioned above) to one of the operations that returns elements with both serializable and datacontract. I'll refactor out the serializable first and test. I'm using the abstract for a whole different reason. I just pasted a very trimmed version of it. Thanks, I'll test and show my results here.
Nathan
If the first doesn't work, I'll try your composition solution. Thanks!
Nathan
+1  A: 

Okay, after researching these options, I figured out what caused the issue. Ultimately, inheritance and having both attributes, serializable and DataContract, in the data being exchanged did not make a difference with deserializing the response.

The real meat of the issue was in my configuration. Earlier I was playing with Streaming messages. I left my host transferMode set to Streaming and my client was set to Buffered. In silverlight, that's my only option. So the serialization problem happened because the message was being chunked. I noticed this after tracing a few calls.

So easy peasy fix. Switch transferMode to Buffered. I'm going to setup a separate endpoint for streaming and play with that another time. I don't need to stream the CRUD services.

Thanks for everyone's input.

-Nathan

Nathan