I'm writing my first WCF service. I decided to write the service just as a DLL to begin with and then aspect the WCF stuff on afterwards which is where I am now.
I was advised by the architect that I should stick to a specific format for message objects which I have done. However I've used Interfaces, complex types and lists thereof in my message objects. I'm coming to adding the attributes on and I'm getting a bit confused.
Here's a show example of my code.
[ServiceContract] public interface MyServiceContract { [OperationContract] MyMethodResponseMessage MyMethod(MyMethodRequestMessage request); } public class MyService : MyServiceContract { public MyMethodResponseMessage MyMethod(MyMethodRequestMessage request) { //Do things } } //Messages [MessageContract] public class MyMethodResponseMessage { [MessageBodyMember] public MyMethodResponse Body { get; set; } } [DataContract] public class MyMethodResponse { [DataMember] public IMyComplexTypeItem { get; set; } [DataMember] public List<IMyComplexType> Items { get; set; } [DataMember] public bool Success { get; set; } } //DTO public interface IMyComplexType { [DataMember] string Identity { get; set; } } [DataContract] public class MyComplexType1 : IMyComplexType { [DataMember] public virtual string Identity }
Can anyone comment on the correctness in the use of MessageContract, DataContract, DataMember and Serializable etc? Any pointers or glaring mistakes?
Also which serializer is the best one to use? and what is the best strategy to ensure I get well formed XML from this so that other clients can consume my service easily?
No, the DataContractAttribute is not required - WCF will infer serialization rules.
A message contract is used to control the structure of a message body and serialization process. It is used to send/access the information in the soap header. By use of a Message Contract we can customize the parameters sent using a SOAP message between the client and the server.
A data contract is a formal agreement between a service and a client that abstractly describes the data to be exchanged. That is, to communicate, the client and the service do not have to share the same types, only the same data contracts.
Re the request/response - a [DataContract]
would work just as well. One of the advantages of message-contracts is that you can set privacy against members, but in many cases this isn't necessary. In such cases, I prefer to keep the contract as simple as possible, just as a data-contract.
Re which serializer - that is largely a factor of the configuration. By default over http, for example, it will be DataContractSerializer
.
I'm not sure, however, that the list of IMyComplexType
is going to work very well. You could try, but generally it wants concrete types. Note that with base-classes you can use [KnownType]
to specify the allowed sub-types.
Note that unlike XmlSerializer
, it is not a requirement for collection members to have setters - although you might need to add an OnDeserializing
callback method to initialize the list if you do that (WCF doesn't call constructors).
Aside: you can also use protobuf-net with data-contracts and WCF (as long as they have an explicit Order); this is more densely packed than the regular xml. It has no support for message-contracts at the moment, though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With