WCF


·         Windows Communication Foundation (WCF) introduced in .NET Framework 3.0
·         What was before WCF for distributed applications: .Net Remoting, Web Services
o   .Net Remoting: Both Client and Service should be of same technology i.e. .Net. We can use these services with other applications but we should be careful about data types that we are using. We cannot use some classes of .Net e.g: Activator to activate .Net remote service
o   Web Service: different protocols and message formatting needs different service hosting
·         In WCF, using endpoints we can overcome both above problems
·         System.ServiceModel is the core assembly of WCF. All required attributes and classes are present in this assembly
·         Sample WCF Configuration
<configuration>
  <system.serviceModel>
    <services>
      <service name=”Namespace.ClassNamebehaviorConfiguration=”mexBehaviorConfigName”>
        <endpoint address=”ServiceName” binding=”basicHttpBinding” contract=”Namespace.InterfaceName”></endpoint>
               <endpoint address=”ServiceName” binding=”netTcpBinding” contract=”Namespace.InterfaceName”></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
        <host>
        <baseAddresses>
            <add baseAddress=”http://localhost:8080/” />
            <add baseAddress=”net.tcp://localhost:8090/” />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name=”mexBehaviorConfigName”>
          <serviceMetadata httpGetEnabled=”true”/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>
·         Mex binding is mandatory to get WSDL document, which is contains all the metadata of service
·         We can use name attribute of Service Contract to prevent from breaking the service in case of any change in service name. e.g. [ServiceContract(name=”NameKnownToClient”)]. This sets the PortType property in WSDL which is used to identify the service. So though we change the service name (i.e. name of interface), client will be able to access the service using the name provided in name attribute. Same we can use for Operation Contracts as well.
·         With respect to WCF, Serialization is the process of converting an object into the XML representation and the reverse process is known as Deserialization
·         By default WCF uses DataContractSerialization. We can serialize an object using either Serializable attribute or DataContract attribute.
·         .Net 3.5 and above don’t need to explicitly use DataContract or DataMember attribute. Data Contract Serializer will automatically serialize all your public properties (except private fields and properties) in alphabetically.
·         If we use [Serializable] attribute to serialize object then DataContractSerializer will serialize all the fields [including private fields]. We don’t have explicit control on which fields to be serialized.
·         If we use [DataContract] attribute to serialize object, then DataContractSerializer will serialize only fields marked with [DataMember] attribute. Other fields/ properties are excluded.
·         [Datamember] can be applied on both public as well as private fields/ properties
·         [DataContract(Namespace=”http://localhost:8080/anyName”)] used to set custom namespace.
·         [DataMember(Name=”name”, Order= 1)] used to set custom name and order of the member.
·         WCF service generally accepts and returns base type, if we want to accept and return inherited types then we use [KnownType(typeof(DerivedClassName))] attribute on top of [DataContrtact]. E.g. Employee, PartTime, FullTime then use [KnownType(typeof(PartTime))] on Employee class
·         If we use KnownType attribute on DataContract i.e. base class then we will get access of those derived classes everywhere where we are using the base class. For more granularity we can use [ServiceKnownType(typeof(derivedClass))] with ServiceContract or OperationContract. If we use it with ServiceContract then we will get access of those KnownTypes in that Service only. If we use it with OperationContract then we will get access of those KnownTypes in that Operation only. We can define KnownTypes in configuration file also, it will work same as declaring knownType on DataContract
·         To enable message logging and tracing: right click on configuration file and click on Service Configuration Editor (also get in Tools), in editor, select Diagnostics, and click on Enable Auto Flush, Enable Message Logging and Enable Tracing. It creates two log files i.e. web_messages.svclog and web_tracelog.svclog in root folder. Then under Diagnostics select Message Logging, and set Log Entire Message to True. Open these log files to see logs  in MS Service Trace Viewer
·         DataContract gives us limited control over SOAP message like we can set name and/or order of the elements. On the other hand MessageContract gives us full control over SOAP message using MessageHeader and MessageBodyMember
·         In general we use MessageContract if we want to modify the structure of the SOAP XML message or wants to add some additional information (like User Credentials) in header section
·         Apply [MessageContract] attribute to make a class Message Contract. Apply [MessageHeader] attribute on property that you want to include in SOAP Header. Apply [MessageBodyMember] on property that you want to include in the SOAP body section.
·         WCF uses IExtensibleDataObject to preserve unknown elements. If any unknown elements of data within the XML is received at the service side then those unknown elements can be stored in ExtensionData property of type ExtensionDataObject from interface IExtensibleDataObject
·         The downside of using IExtensibleDataObject is the risk of Denial of Service [DOS] attack. The attacker might flood the server with the requests containing large amount of unknown elements which can lead to system out of memory and DOS. To avoid this, we need to remove implementation of IExtensibleDataObject but this will not work if we have large amount of data contracts. We can enable/ disable IExtensibleDataObject using Service Behavior configuration
<behaviors>
  <serviceBehaviors>
    <behavior name=”ignoreExtensionData”>
      <dataContractSerializer ignoreExtensionDataObject=”true” />
    </behavior>
  </serviceBehaviors>
</behaviors>
·         We can enable/ disable IExtensibleDataObject by using ServiceBehavior attribute on Service Contract like: [ServiceBehavior(IgnoreExtensionDataObject = true)]
·         Whenever exception occurs in WCF service, the exceptions are serialized in to SOAP fault before returned to the client. By default exception details are not included in SOAP Fault
·         For debugging purpose if we want to add exception details in SOAP fault/ result then we need to enable includeExceptionDetailInFaults setting in configuration as below:
<behaviors>
  <serviceBehaviors>
    <behavior name=”behaviorName”>
      <serviceDebug includeExceptionDetailInFaults=”true” />
    </behavior>
  </serviceBehaviors>
</behaviors>
·         Same setting we can do in code using [ServiceBehavior(IncludeExceptionDetailInFaults=true)]
·         An Unhandled exception in WCF service will cause the communication channel to fault and the session will be lost. Once communication channel is in faulted state, we cannot use the same instance of proxy class. BasicHttpBinding does not have sessions, so though an unhandled exception faults the server channel, the client proxy is still ok because this channel does not maintain any session. wsHttpBinding have secure session, so when the unhandled exception occurs it torn downs the communication channel and the session along with it. So once the channel is in fault state, client will not be able to access the service using same instance of proxy class.
·         To handle such unhandled exceptions we use FaultException instead of DOT Net exceptions. DOT NET exceptions are platform specific, these exception needs client of same technology i.e. DOT NET. Though we use DOT NET exceptions to handle WCF service exceptions, those exceptions are not handled by WCF so this causes the communication to be in faulted stated. So to maintain interoperability and keep server session alive (after exception also) we use FAULTEXCEPTION.
·         We can throw a generic SOAP fault using FaultException class but instead of throwing generic fault we can create strongly typed SOAP Fault with some additional details about exception and throw them.  We can throw strongly typed fault by creating data contract for the fault with custom data as: throw new FaultException<DataContractForFault>(objFault);
·         In Asp.Net we use Application_Error() event to handle all exceptions. In WCF, to centralize the exception handling, we implement IErrorHandler interface. IErrorHandler provides us two methods bool HandleError(Exception), void ProvideFault(Exception, MessageVersion, ref Message fault)
·         ProvideFault() method gets called automatically when there is an any unhandled exception or fault. We can convert unhandled error into generic fault here which can be returned to client. HandleError() method is gets called asynchronously after ProvideFault() is executed and error message is returned to the client. Here we can write code to log the error in database without blocking client call.
·         We need to add a Custom Service Behavior Attribute to let WCF know that we want to use GlobalErrorHandler whenever unhandled exception occurs. We can add this custom behavior by implementing an interface IServiceBahavior and implementing ApplyDispatcherBehavior() method. Then add [GlobalErroHandlerBehavior(typeof(ClassNameImplementedIErrorHandler))] attribute on top of service.
·         We can host WCF service by following ways:
o   Self Hosting: Using ServiceHost class in Console Application or Windows Form Application
o   Windows Service: Using ServiceHost class in Windows Service Application
o   Internet Information Services: Hosting within IIS (Supports only http bindings)
o   Windows Activation Service: Hosting using IIS7 with WAS support (Supports all bindings)
·         Self Hosting: Easy to setup, Easy to debug, Supports all bindings, easy to control service lifetime using Open() and Close() functions. This requires Host always running, custom code required to host
·         Windows Service: Create Windows Service Application and add same code as in self hosting in OnStart() and OnStop() handlers. Right Click in service design and select Add Installer which will add a installer.cs file with Service Installer and Process Installer. We can set Start Type (Manual/ Automatic) in Service Installer and Account (i.e. user/ local system) in Process Installer. Use installutil -i <path of Windows service exe> command in VS command prompt to install service. We can see services using services.msc in run window.
·         Using Windows Service hosting we can automatically start service when the system starts without any user login, we can configure what should happen in case of service failure (from Recovery tab of installed service), supports all binding. Need custom code to host service, windows service needs to install on server, difficult to debug (need to attach process of installed service)