Friday, 29 May 2015

Exception Handling in WCF - Creating and Throwing Strongly Typed SOAP Fault

His can be achieved by 3 simple steps.

step 1 - Create a class that represents your SOAP fault, Decorate the class with [DataContract] attribute and the properties with [DataMember] attribute.

   [DataContract]
    public class DivideByZeroFault
    {
        [DataMember]
        public string Error { get; set; }
        [DataMember]
        public string Details { get; set; }
    }

step 2 - In the service data contract, use] FaultContract] attribute to specify which operations can throw which SOAP faults.

 [ServiceContract]    
    public interface IService1
    {        

        [FaultContract(typeof(DivideByZeroFault))]
        [OperationContract]
        float Divide(int val1,int val2);
       
    }


step 3 -in the service implementation create an instance of the strongly typed SOAP fault and throw it using FaultException<T>

 public class Service1 : IService1
    {
        
        public float Divide(int val1, int val2)
        {
            try
            {
                return val1 / val2;
            }
            catch (DivideByZeroException ex)
            {
                DivideByZeroFault divideByZeroFault = new DivideByZeroFault();
                divideByZeroFault.Error = ex.Message;
                divideByZeroFault.Details = "Denominator cannot be zero";

                throw new FaultException<DivideByZeroFault>(divideByZeroFault);
            }
        }
          
    }


Note : Centralize exception handling in wcf can be achieved by implementing IErrorHandler interface.


Exception Handling in WCF - Unhandled Exception in WCF

An unhandled exception in wcf service, will cause the communication channel to fault and the session will be lost.Once a communication channel is in faulted state, we can not use the same instance of the proxy class any more. we have to create a new instance of the proxy class.But this is not true for basicHttpBinding.

BasicHttpBinding does not have session, so when there is unhandled exception, it only fault the server channel.the client proxy is still OK, because with BasicHttpBinding the channel is not maintaining sessions and when the client calls again it is not expecting the channel to maintain any session.

wsHttpBinding has secure session, so when there is an unhandled exception, it fault the server channel.At this point the client proxy is useless as it is also faulted.
because with wsHttpBinding the channel is maintaining a secure session and when the client calls again it expects the channel to maintain the same session.The same session does not exist at the server channel any more, as the unhandled exception has already torn down the channel and the session along with.

If You are using wsHttpBinding, if any unhandled exception occur in wcf service, after that you can not use same client proxy object.At that case you must have to re-instantiate proxy object.

Related Post :

Different-option-of-hosting-wcf-service
Binding-in-wcf-choosing-right-wcf
Exchanging-metadata-in-wcf
Some-interesting-facts-about-data-contract
Knowntype-attribute-in-wcf
Associating-knowntype-in-wcf
Message-contract-in-wcf
Exception-handling-in-wcf
Exception Handling in WCF - SOAP Fault in WCF
Exception Handling in WCF - Unhandled Exception in WCF
Exception Handling in WCF - Creating and Throwing Strongly Typed SOAP Fault

Thursday, 28 May 2015

Exception Handling in WCF - SOAP Fault in WCF

WCF serializes exception to SOAP faults before reporting the exception information to the client.this is because exceptions are not allowed to be passed through a service channel.

SOAP faults are in xml format and are platform independent.
A typical SOAP fault contains FaultCode, FaultReason and Detail elements.

The detail element can be used to include any custom xml.

SOAP faults are formatted based on SOAP1.1 or SOAP1.2 specifications depending on the binding .
BasicHttpBinding uses SOAP1.1 whereas other bindings use SOAP1.2.

Following xml is the response SOAP xml if any unhandled exception occur in WCF service.

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
     <s:Fault>
         <faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher" xmlns="">a:InternalServiceFault</faultcode>
<faultstring xml:lang="en-GB" xmlns="">The server was unable to process the request
 due to an internal error.  For more information about the error,
either turn on IncludeExceptionDetailInFaults
(either from ServiceBehaviorAttribute or from the <serviceDebug>configuration behavior)
on the server in order to send the exception information back to the client,
or turn on tracing as per the Microsoft .NET Framework 3.0 SDK
 documentation and inspect the server trace logs.
        </faultstring>
      </s:Fault>
  </s:Body>
</s:Envelope>

In above xml, actual reason is not serialize in SOAP fault. if you want to show actual reason allow includeExceptionDetailInFaults in config file.

<behaviors>
      <serviceBehaviors>
        <behavior name="mexBehaviour">        
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

Now the response xml will be as follows.

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <s:Fault>
        <faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher" xmlns="">a:InternalServiceFault
        </faultcode>
        <faultstring xml:lang="en-GB" xmlns="">Attempted to divide by zero.
        </faultstring>
        <detail xmlns="">
          <ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
         <HelpLink i:nil="true"></HelpLink>
         <InnerException i:nil="true"></InnerException>
         <Message>Attempted to divide by zero.</Message>
         <StackTrace>
at HelloWCFService.Service1.Divide(Int32 val1, Int32 val2) in C:\Users\npdrsaini\documents\visual studio 2010\Projects\HelloService\HelloWCFService\Service1.svc.cs:line 33at SyncInvokeDivide(Object , Object[], Object[])at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[]inputs, Object[]&outputs)at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&rpc)at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&rpc)at  System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
         </StackTrace>
         <Type>System.DivideByZeroException</Type>
       </ExceptionDetail>
     </detail>
   </s:Fault>
</s:Body>
</s:Envelope>


Above message format is SOAP1.1 if you want to see SOAP1.2 some changes needed.
change the binding from basicHttpBinding to wsHttpBinding.
By default message  Security is turned on for wsHttpBinding.Set the security mode for wsHttpBinding to None,so we could view the SOAP1.2 fault message.

 <bindings>
      <wsHttpBinding>
        <binding>
          <security mode="None"></security>
        </binding>
      </wsHttpBinding>
   </bindings>

SOAP1.2 message format for same response will be as follows :

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher/fault</a:Action>
<a:RelatesTo>urn:uuid:47e00c8f-ca12-4e05-8321-46ff8fa69c79</a:RelatesTo>
<ActivityId CorrelationId="bba96711-ee01-4f2c-a5b2-f53af7975901" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">5e2bc13f-f61c-4ba9-8b1b-328db1823108</ActivityId>
</s:Header>
<s:Body>
<s:Fault>
<s:Code>
<s:Value>s:Receiver</s:Value>
<s:Subcode>
<s:Value xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</s:Value>
</s:Subcode>
</s:Code>
<s:Reason>
<s:Text xml:lang="en-GB">Attempted to divide by zero.</s:Text>
</s:Reason>
<s:Detail>
<ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<HelpLink i:nil="true"></HelpLink>
<InnerException i:nil="true"></InnerException>
<Message>Attempted to divide by zero.</Message>
<StackTrace>
at HelloWCFService.Service1.Divide(Int32 val1, Int32 val2) in C:\Users\npdrsaini\documents\visual studio 2010\Projects\HelloService\HelloWCFService\Service1.svc.cs:line 33at SyncInvokeDivide(Object , Object[], Object[])at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[]inputs, Object[]&outputs)at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&rpc)at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&rpc)at  System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
</StackTrace>
<Type>System.DivideByZeroException</Type>
</ExceptionDetail>
</s:Detail>
</s:Fault>
</s:Body>

</s:Envelope>


Code implementation :

     [ServiceContract]  
    public interface IService1
    {    

        [OperationContract]
        float Divide(int val1,int val2);
     
    }

  public class Service1 : IService1
    {
     
        public float Divide(int val1, int val2)
        {
            return val1 / val2;
        }
       
    }

Client side code : 

public partial class TestClient : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void btn_getEmp_Click(object sender, EventArgs e)
    {
        Service1Client ocjClient = new Service1Client("WSHttpBinding_IService1");
     
        float result = ocjClient.Divide(10, 0);
    }
}

Related Post :

Different-option-of-hosting-wcf-service
Binding-in-wcf-choosing-right-wcf
Exchanging-metadata-in-wcf
Some-interesting-facts-about-data-contract
Knowntype-attribute-in-wcf
Associating-knowntype-in-wcf
Message-contract-in-wcf
Exception-handling-in-wcf
Exception Handling in WCF - SOAP Fault in WCF
Exception Handling in WCF - Unhandled Exception in WCF
Exception Handling in WCF - Creating and Throwing Strongly Typed SOAP Fault


Exception Handling in WCF

When an exception occur in WCF service, the service serializes the exception into a SOAP fault, and then sends the fault to client.

By default unhandled exception details are not included in SOAP faults due to security reasons so client is unable to know the actual reason of exception.

If we want to include exception details in SOAP faults we have to enable IncludeExceptionDetailInFaultSetting. this can be done by one of the following ways.

1- In the config file using service behaviour configuration

<behaviors>
      <serviceBehaviors>
        <behavior name="mexBehaviour">        
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
   </behaviors>


2- in code using ServiceBehaviour attribute

[ServiceBehavior(IncludeExceptionDetailInFaults=true)]

Related Post :

Different-option-of-hosting-wcf-service
Binding-in-wcf-choosing-right-wcf
Exchanging-metadata-in-wcf
Some-interesting-facts-about-data-contract
Knowntype-attribute-in-wcf
Associating-knowntype-in-wcf
Message-contract-in-wcf
Exception-handling-in-wcf
Exception Handling in WCF - SOAP Fault in WCF
Exception Handling in WCF - Unhandled Exception in WCF
Exception Handling in WCF - Creating and Throwing Strongly Typed SOAP Fault

Wednesday, 27 May 2015

WCF Backward Compatibility and Versioning Strategies

Once services are hosted to production, their associated WSDL documents – which describe service endpoints, protocols and related contracts – must not be changed. Or, at a minimum, any changes should be backward compatible so that existing clients are not affected when changes are published. followings are the few versioning strategies that you might consider for your WCF applications.

Service contracts and backward compatibility

Adding new parameters to an operation signature :
If we add more parameters in operation contract client will be unaffected and new parameter will be initialize with default value

In following example if we add one more parameter in operation contract signature, whereas client has implemented it with one parameter, client will be unaffected and newParameter will be initialize with default value.

       [OperationContract]
        Employee getEmoloyee(int id);

        [OperationContract]
        Employee getEmoloyee(int id, string newParameter);

Removing parameters from an operation signature :
Client will be unaffected. Superfluous parameters pass by clients are ignored, extra data lost at the service.

        [OperationContract]
        Employee getEmoloyee(int id);

        [OperationContract]
        Employee getEmoloyee();

Modifying parameter types :
An exception will occur if the incoming type from the client cannot be converted to the parameter data type.

        [OperationContract]
        Employee getEmoloyee(int id);

        [OperationContract]
        Employee getEmoloyee(Datetime id);

Above signature change from integer to datetime affect client and throw exception at run time because integer is not compatible with datetime but below operation contract signature will work.

        [OperationContract]
        Employee getEmoloyee(double id);

Modifying return value types :
An exception will occur if the return value from the service cannot be converted to the expected data type in the client version of the operation signature.

Adding new operations :
Client unaffected. Will not invoke operations it knows nothing about.

Removing operations :
An exception will occur. Messages sent by the client to the service are considered to be using an unknown action header.


Data contracts and backward compatibility 


Add new non-required members :
Client unaffected. Missing values are initialized to defaults.

Add new required members :
An exception is thrown for missing values.

Remove non-required members:
Data lost at the service. Unable to return the full data set back to the client, for example. No exceptions.

Remove required members:
An exception is thrown when client receives responses from the service with missing values.

Modify existing member data types:
If types are compatible no exception but may receive unexpected results.

Related Post :

Different-option-of-hosting-wcf-service
Binding-in-wcf-choosing-right-wcf
Exchanging-metadata-in-wcf
Some-interesting-facts-about-data-contract
Knowntype-attribute-in-wcf
Associating-knowntype-in-wcf
Message-contract-in-wcf
Exception-handling-in-wcf
Exception Handling in WCF - SOAP Fault in WCF
Exception Handling in WCF - Unhandled Exception in WCF
Exception Handling in WCF - Creating and Throwing Strongly Typed SOAP Fault




Monday, 25 May 2015

Message Contract in WCF.

Data contract provide us limited control over request and response XML messages in WCF.If we want full control over request and response xml use MessageContract.

  • In general user message contract only if there is a reason ti tweak the structure of soap xml message.
  • If we want to include some custom data in soap header we can use message contract. Refer following example.

    [MessageContract]
    public class EmployeeRequest
    {
        [MessageHeader(Namespace="http://abc.com/empReqObj")]
        public string tokenKey { get; set; }      
    }

  • Want to change the name of wrapper element in soap message use message contract.Wrapper element is nothing but the name of operation contract.In below soap request message getEmployee is a wrapper element.
<s:Body>
       <getEmoloyee xmlns="http://tempuri.org/">
             <id>1</id>
       </getEmoloyee>
</s:Body>
  • Message contract attribute has following parameters .
  1. IsWrapper
  2. WrapperName
  3. WrapperNamespace
  4. ProtectionLevel
  • Message header attribute is applied on property of the class that you want to include in soap header section.
  • Message body attribute is applied on property of the class that you want to include in soap body section.
 [MessageContract( WrapperName="EmployeeReqObject", IsWrapped=true,  WrapperNamespace="http://abc.com/empReqObj")]
    public class EmployeeRequest
    {
        [MessageHeader(Namespace="http://abc.com/empReqObj")]
        public string tokenKey { get; set; }
        [MessageBodyMember(Namespace="http://abc.com/empReqObj")]
        public int EmployeeID { get; set; }
    }

Programming Example :

Soap request request and response messages without using message contract is as follows.

Req soap xml :

 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
     <s:Header>
     </s:Header>
     <s:Body>
         <getEmoloyee xmlns="http://tempuri.org/">
              <id>1</id>
         </getEmoloyee>
      </s:Body>
</s:Envelope>

Response soap xml :

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Header></s:Header>
    <s:Body>
        <getEmoloyeeResponse xmlns="http://tempuri.org/">
        <getEmoloyeeResult i:type="b:FullTimeEmployee" xmlns:a="http://abc.com/employee"
         xmlns:b="http://schemas.datacontract.org/2004/07/WcfService1">
               <a:empAddress>gurgaon</a:empAddress>
               <a:empID>1</a:empID>
               <a:empName>rahul</a:empName>
               <b:HourPaid>1000</b:HourPaid>
               <b:HourWorked>8</b:HourWorked>
               </getEmoloyeeResult>
         </getEmoloyeeResponse>
     </s:Body>
</s:Envelope>









Request and response soap xml after tweaking with message contract :

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
      <h:tokenKey xmlns:h="http://abc.com/empReqObj">GHR45TY56HJ</h:tokenKey>
      <ActivityId CorrelationId="e9898ec9-1a36-4d7d-b41e-85d536d8f8b2"
       xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">a6ff8893-293d-4476
      -8f4a-cdefb16ca5fa</ActivityId>
</s:Header>
<s:Body>
        <EmployeeReqObject xmlns="http://abc.com/empReqObj">
           <EmployeeID>1</EmployeeID>
        </EmployeeReqObject>
</s:Body>
</s:Envelope>


<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header></s:Header>
<s:Body>
     <EmployeeInfoObject xmlns="http://abc.com/empReqObj">
        <EmployeeID>1</EmployeeID>
        <EmployeeName>rahul</EmployeeName>
        <EmployeeAddress>gurgaon</EmployeeAddress>
        <EmployeeHourPay>1000</EmployeeHourPay>
        <EmployeeHourWork>8</EmployeeHourWork>
        <EmployeeSalary>0</EmployeeSalary>
        <EmployeeType>1</EmployeeType>
     </EmployeeInfoObject>
</s:Body>
</s:Envelope>


C#  Code:


 [MessageContract( WrapperName="EmployeeReqObject", IsWrapped=true, WrapperNamespace="http://abc.com/empReqObj")]
    public class EmployeeRequest
    {
        [MessageHeader(Namespace="http://abc.com/empReqObj")]
        public string tokenKey { get; set; }
        [MessageBodyMember(Namespace="http://abc.com/empReqObj")]
        public int EmployeeID { get; set; }
    }

    [MessageContract(WrapperName = "EmployeeInfoObject", IsWrapped = true, WrapperNamespace = "http://abc.com/empReqObj")]
    public class EmployeeInfo
    {
        public EmployeeInfo()
        { }
        public EmployeeInfo(Employee emp)
        {
            this.EmployeeID = emp.empID;
            this.EmployeeName = emp.empName;
            this.EmployeeAddress = emp.empAddress;
            this.EmployeeType = emp.empType;
            if (emp.empType == 2)
                this.EmployeeSalary = ((PartTimeEmployee)emp).Salary;
            else
            {
                this.EmployeeHourPay = ((FullTimeEmployee)emp).HourPaid;
                this.EmployeeHourWork = ((FullTimeEmployee)emp).HourWorked;
            }
        }
        [MessageBodyMember(Namespace = "http://abc.com/empReqObj", Order = 1)]
        public int EmployeeID { get; set; }
        [MessageBodyMember(Namespace = "http://abc.com/empReqObj", Order = 2)]
        public string EmployeeName { get; set; }
        [MessageBodyMember(Namespace = "http://abc.com/empReqObj", Order = 3)]
        public string EmployeeAddress { get; set; }

        [MessageBodyMember(Namespace = "http://abc.com/empReqObj", Order = 3)]
        public int EmployeeSalary { get; set; }

        [MessageBodyMember(Namespace = "http://abc.com/empReqObj", Order = 3)]
        public int EmployeeHourPay { get; set; }

        [MessageBodyMember(Namespace = "http://abc.com/empReqObj", Order = 3)]
        public int EmployeeHourWork { get; set; }


        [MessageBodyMember(Namespace = "http://abc.com/empReqObj", Order = 3)]
        public int EmployeeType { get; set; }

    }
   


    //[KnownType(typeof(PartTimeEmployee))]
    //[KnownType(typeof(FullTimeEmployee))]
    [DataContract(Namespace="http://abc.com/employee")]
    public class Employee
    {
        [DataMember]
        public int empID { get; set; }
        [DataMember]
        public string empName { get; set; }
        [DataMember]
        public string empAddress { get; set; }
        [DataMember]
        public int empType { get; set; } //1 for full time and 2 for part time

    }
    public class PartTimeEmployee : Employee
    {
        public int Salary { get; set; }
    }
    public class FullTimeEmployee : Employee
    {
        public int HourWorked { get; set; }
        public int HourPaid { get; set; }
    }






IService1.cs :


 [ServiceContract]
    public interface IService1
    {

        [OperationContract]
        void saveEmoloyee(EmployeeInfo emp);
        [OperationContract]
        EmployeeInfo getEmoloyee(EmployeeRequest req);
              
        // TODO: Add your service operations here
    } 


 Service1.svc.cs :

public class Service1 : IService1
    {

        public void saveEmoloyee(EmployeeInfo emp)
        {
        //code for save here 
        }

        public EmployeeInfo getEmoloyee(EmployeeRequest req)
        {
            Employee emp = null;
            if (req.EmployeeID == 1)
            {
                emp = new FullTimeEmployee { empID = 1, empType=1, empAddress = "gurgaon", empName = "rahul", HourPaid = 1000, HourWorked = 8 };
            }
            else
            {
                emp = new PartTimeEmployee { empID = 1, empType=2, empAddress = "gurgaon", empName = "rahul", Salary = 50000 };
            }
            return new EmployeeInfo(emp);
        }
    }


ClientApplication.aspx.cs :


 protected void btn1_Click(object sender, EventArgs e)
        {
            ServiceReference1.EmployeeRequest objReq = new ServiceReference1.EmployeeRequest();
            ServiceReference1.EmployeeInfo empInfo = new ServiceReference1.EmployeeInfo();
            objReq.EmployeeID = 1;
            objReq.tokenKey = "GHR45TY56HJ";

            ServiceReference1.IService1 client = new ServiceReference1.Service1Client();
            empInfo = client.getEmoloyee(objReq);

            if (empInfo.EmployeeType == 1)
            {
                string name = empInfo.EmployeeName;
                int hourPaid = empInfo.EmployeeHourPay;
                int hourworked = empInfo.EmployeeHourWork;
            }
            else
            {
                int salary = empInfo.EmployeeSalary;
            }
           
        }




Related Post :

Different-option-of-hosting-wcf-service
Binding-in-wcf-choosing-right-wcf
Exchanging-metadata-in-wcf
Some-interesting-facts-about-data-contract
Knowntype-attribute-in-wcf
Associating-knowntype-in-wcf
Message-contract-in-wcf
Exception-handling-in-wcf
Exception Handling in WCF - SOAP Fault in WCF
Exception Handling in WCF - Unhandled Exception in WCF
Exception Handling in WCF - Creating and Throwing Strongly Typed SOAP Fault











Friday, 22 May 2015

Weekend Challenge for software developer and SQL developer !!!! (Asked in Interview)

Hello All,
This is one of the interview question asked from me.
Hope this will help you to write some tricky query.Try this!!!


Fuel in ltr    |        Date
--------------------------------
11          | 10/01/15
--------------------------------
09          | 11/01/15
--------------------------------
15          | 12/01/15
--------------------------------
12          | 13/01/15
--------------------------------
08          | 14/01/15
--------------------------------
13          | 15/01/15
--------------------------------
10          | 16/01/15
--------------------------------
16          | 17/01/15



Above table shows quantity of fuel in car on date like 11 ltr on date 10, 9 ltr on date 11, 15 ltr on date 12 and so on.
See row 3rd,  fuel become 15 from 9, means car owner refill 6 ltr fuel on date 12.
Challenge is that you have to find all rows with date and quantity of refill fuel on that date.

Ans should be like that :


Fuel in ltr    |        Date
--------------------------------
06          | 12/01/15
--------------------------------
05          | 15/01/15
--------------------------------
06          | 17/01/15


Please comment your answer.



Associating KnownType in WCF

There are 4 different ways to associate [KnownType]

1-) Use KnownType attribute on base type,This option is global, that is all service contracts and all operation contracts will respect the known types.


[KnownType(typeof(PartTimeEmployee))]
    [KnownType(typeof(FullTimeEmployee))]
    [DataContract]
    public class Employee
    {
        [DataMember]
        public int empID { get; set; }
        [DataMember]
        public string empName { get; set; }
        [DataMember]
        public string empAddress { get; set; }    
     
    }
    public class PartTimeEmployee : Employee
    {    
        public int Salary { get; set; }
    }
    public class FullTimeEmployee : Employee
    {    
        public int HourWorked { get; set; }      
        public int HourPaid { get; set; }
    }


2-) Apply [ServiceKnownType] attribute on the [ServiceContract] : with this option the known types are respected by all operation contracts within this service contract only.

[ServiceKnownType(typeof(PartTimeEmployee))]
    [ServiceKnownType(typeof(FullTimeEmployee))]
    [ServiceContract]  
    public interface IService1
    {

        [OperationContract]
        void saveEmoloyee(Employee emp);

     
        [OperationContract]
        Employee getEmoloyee(int id);
     
    }


3-) If you want even more granual control, then apply [ServiceKnownType] attribute on specific operation contracts. With this option, only the operation contracts that are decorated with ServiceKnownType attribute.

[ServiceContract]  
    public interface IService1
    {

        [OperationContract]
        void saveEmoloyee(Employee emp);

        [ServiceKnownType(typeof(PartTimeEmployee))]
        [ServiceKnownType(typeof(FullTimeEmployee))]
        [OperationContract]
        Employee getEmoloyee(int id);
     
    }

4-) Specify known types in configuration file. this is equivalent to applying known type attribute on base typpe means this is applicable globally.

Related Post :

Different-option-of-hosting-wcf-service
Binding-in-wcf-choosing-right-wcf
Exchanging-metadata-in-wcf
Some-interesting-facts-about-data-contract
Knowntype-attribute-in-wcf
Associating-knowntype-in-wcf
Message-contract-in-wcf
Exception-handling-in-wcf
Exception Handling in WCF - SOAP Fault in WCF
Exception Handling in WCF - Unhandled Exception in WCF
Exception Handling in WCF - Creating and Throwing Strongly Typed SOAP Fault

KnownType attribute in WCF

In WCF if we have classes related by inheritence, WCF service generally accept and returns the basse type.if you expect the service to accept and return inherited types than use knownType attribute.

    [KnownType(typeof(PartTimeEmployee))]
    [KnownType(typeof(FullTimeEmployee))]
    [DataContract]
    public class Employee
    {
        [DataMember]
        public int empID { get; set; }
        [DataMember]
        public string empName { get; set; }
        [DataMember]
        public string empAddress { get; set; }    
     
    }
    public class PartTimeEmployee : Employee
    {    
        public int Salary { get; set; }
    }
    public class FullTimeEmployee : Employee
    {    
        public int HourWorked { get; set; }      
        public int HourPaid { get; set; }
    }

If you remove [KnownType] from above code, in wsdl file metadata for classes FullTimeEmployee and PartTimeEmployee will not exist.

You can't use drived classes PartTimeEmployee and FullTimeEmployee in client side untill you don't use [KnownType] attribute.

Client Code :
 protected void btn_getEmp_Click(object sender, EventArgs e)
    {
        ServiceReference1.Service1Client ocjClient = new ServiceReference1.Service1Client();
        ServiceReference1.Employee obj = new ServiceReference1.Employee();
        obj = ocjClient.getEmoloyee(1);
        int hourPaid = ((ServiceReference1.FullTimeEmployee)obj).HourPaid;
        int hourworked = ((ServiceReference1.FullTimeEmployee)obj).HourWorked;
     
        ServiceReference1.Employee obj2 = new ServiceReference1.Employee();
        obj2 = ocjClient.getEmoloyee(2);
        int salary = ((ServiceReference1.PartTimeEmployee)obj).Salary;
    }

Above client code will give error if you remove [KnownType] from employee class.

Related Post :

Different-option-of-hosting-wcf-service
Binding-in-wcf-choosing-right-wcf
Exchanging-metadata-in-wcf
Some-interesting-facts-about-data-contract
Knowntype-attribute-in-wcf
Associating-knowntype-in-wcf
Message-contract-in-wcf
Exception-handling-in-wcf
Exception Handling in WCF - SOAP Fault in WCF
Exception Handling in WCF - Unhandled Exception in WCF
Exception Handling in WCF - Creating and Throwing Strongly Typed SOAP Fault


Thursday, 21 May 2015

SQL Query – Order of execution

When you execute a SQL Query, it will be executed in the following sequence :

FROM

ON

JOIN

WHERE

GROUP BY

HAVING

SELECT

DISTINCT

ORDER BY

TOP

Some Interesting Facts About Data Contract, Data Member and Serialization in WCF

This summary is not available. Please click here to view the post.

Wednesday, 20 May 2015

Exchanging metadata in WCF

There are two ways to exchange metadata with client.
1> MexHttpBinding 

2> WSDL :  In the Service Behaviors set httpGetEnabled="true"

Configuration part that affect metadata  :
ServiceMetadata behaviour : This behaviour controls whether metadata is created for the service.When this behaviour is used, the service is scanned, and metadata is created for the service’s contracts.
If the behaviour is not used, no metadata will be created for the service, and you will not be able to create MEX endpoints.

HttpGetEnabled flag : This flag defines whether the metadata will be accessible by an http get request. If this attribute is set to true, then a default url will be created for the metadata (usually the service’s address with the suffix of  ‘?wsdl’). The url will lead you to a WSDL file containing the description of the service operations.
If you do not set this attribute to true, you will not be able to access the metadata using http get requests

MEX endpoint : MEX endpoints are special endpoints that allow clients to receive the service’s metadata by using SOAP messages instead of http get requests. You can create MEX endpoint that can be accessed through http, https, tcp, and even named pipes.

So what is the difference between MEX and WSDL?

MEX and WSDL both output the same thing – a web service description language (WSDL) document, only MEX does it by getting a SOAP message over some transport (http, tcp, named pipes) and returning one message with all the parts, while the WSDL urls use http get requests and require sending several requests to get all the parts.

<system.serviceModel>
      <services>
        <service name="WcfService.Service" behaviorConfiguration="WcfService1.Service1Behavior">
          <endpoint address="" binding="basicHttpBinding" contract="WcfService.IService">          
          </endpoint>
          <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
      </services>
      <behaviors>
        <serviceBehaviors>
          <behavior name="WcfService1.Service1Behavior">
            <serviceMetadata httpGetEnabled="true"/>        
          </behavior>
        </serviceBehaviors>
      </behaviors>
</system.serviceModel>

Related Post :

Different-option-of-hosting-wcf-service
Binding-in-wcf-choosing-right-wcf
Exchanging-metadata-in-wcf
Some-interesting-facts-about-data-contract
Knowntype-attribute-in-wcf
Associating-knowntype-in-wcf
Message-contract-in-wcf
Exception-handling-in-wcf
Exception Handling in WCF - SOAP Fault in WCF
Exception Handling in WCF - Unhandled Exception in WCF
Exception Handling in WCF - Creating and Throwing Strongly Typed SOAP Fault