I'm creating a WCF service, and I'm having a lot of trouble with some Serialization issues. Perhaps there's just 1 way to do it, but i'd like to confirm it Here's my sample code :
Contracts
public interface IAtm { [DataMember] double Latitude { get; set; } [DataMember] double Longitude { get; set; } } [ServiceContract] public interface IAtmFinderService { [OperationContract] ICollection GetAtms(); }
Service Implementation :
[KnownType(typeof(Atm))] [KnownType(typeof(List))] [ServiceKnownType(typeof(Atm))] [ServiceKnownType(typeof(List))] public class AtmFinderService : IAtmFinderService { public ICollection GetAtms() { return new List() { new Atm() { Latitude = 1, Longitude = 1 }, new Atm() { Latitude = 2, Longitude = 2 } }; } }
I added all of the KnownType and ServiceKnownType attributes because i thought that there was something missing there.. So now, i've been doing some tests. I tried creating a console app, using the "add service reference" method to make VS create automatically the proxy. This way, I get a function like
object[] GetAtms();
When trying to call it, i get this error :
The InnerException message was 'Type 'WCFTest.Atm' with data contract name 'Atm:http://schemas.datacontract.org/2004/07/WCFTest' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'.
Very nice... So then, I think that VS's autogenerated code is crap. I did the following change in my service (and all the related classes and implementations) :
[OperationContract] ICollection GetAtms();
So now, i'm returning a concrete type. After updating the service reference, it creates a copy of the Atm class, with its members and stuff. After calling the service, the call succeeds. I thought that this was some bad behaviour related to the autogenerated code, so i tried creating a very simple host/client app. I started a console host listening on some port, then created a client that uses the ClientBase class to make a call to the service. Same behaviour... if the service is implemented returning an interface type, it fails. If i change it to return the concrete type, it works. I think that i have some problem with the KnownType attributes, i must be missing something that the serializer can't process. but i don't know what.