Saturday 13 June 2015

WCF Service Without DataContract Annotation

This can be explained very easily with simple example. I have created RESTful Service which return data in XML and JSON.

# Make on contract that has two services both return DataContract 
  - GetMessageXML() one in XML format and one returns in XML
  - GetMessageJSON() one in JSON format and one returns in JSON

[ServiceContract]
    public interface IService1
    {
        [OperationContract]
        CompositeType GetMessageXML();

        [OperationContract]
        CompositeType GetMessageJSON();
    }


# Below is an implementation of ServiceContract (Note: WebInvoke is used for RESTful service)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public class Service1 : IService1
    {
        [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "GetMessageXML/")]
        //[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "GetMessage/")]
        public CompositeType GetMessageXML()
        {
            return new CompositeType() { StringValue = "test" };
        }

        [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "GetMessageJson/")]
        public CompositeType GetMessageJSON()
        {
            return new CompositeType() { StringValue = "test" };
        }
    }


# Create CompositeType type without DataContract annotation
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
 //[DataContract]
    public class CompositeType
    {        
        string _stringValue = "Hello ";
        DateTime _TimeStamp;        
        
        [DataMember]
        public string StringValue
        {
            get { return _stringValue; }
            set { _stringValue = value; }
        }

        public DateTime TimeStamp
        {
            get { return _TimeStamp; }
            set { _TimeStamp = value; }
        }       
    }


# Service configuration code put it in web.config
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<system.serviceModel>
  <services>
    <service name="WcfServiceIIS.Service1" behaviorConfiguration="serviceBehavior">
    <endpoint address="JSON" binding="webHttpBinding" contract="WcfServiceIIS.IService1" behaviorConfiguration="RestJSONEndpointBehavior"></endpoint>
    <endpoint address="XML" binding="webHttpBinding" contract="WcfServiceIIS.IService1" behaviorConfiguration="RestXMLEndpointBehavior"></endpoint>
    </service>
  </services>
  <behaviors>
   <serviceBehaviors>
    <behavior name="serviceBehavior">
     <serviceMetadata httpGetEnabled="true"/>
     <serviceDebug includeExceptionDetailInFaults="false"/>
    </behavior>
   </serviceBehaviors>
   <endpointBehaviors>        
    <behavior name="RestJSONEndpointBehavior">
     <webHttp helpEnabled="true" defaultOutgoingResponseFormat="Json"/>
    </behavior>
    <behavior name="RestXMLEndpointBehavior">
     <webHttp helpEnabled="true" defaultOutgoingResponseFormat="Xml"/>
    </behavior>
   </endpointBehaviors>
  </behaviors>
  <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
 </system.serviceModel>

So if DataContract is not annotated then by default XmlSerializer is used and thus all public properties are serialized and deserialized
  1. All public properties will be exposed to service consumer. Now think for a second if I want create one property which is required to be exposed to other projects of Solution but not to service consumer
  2. If endpoint behavior has JSON as default response than endpoint throws an error
# Test with Postman - REST Client one can see below response

# I have tried to cover these points following video




No comments:

Post a Comment