Generics in WCF Data Contract

In my WCF training, I often get questions that can we expose a generic type as DataContract in WCF? Yes, WCF allows us to expose the generic types as Data Contract.

Let us say we have a generic type Foo. We can apply data contract on the Foo as follows:

 


  [DataContract]
    public class Foo<T>
    {
        [DataMember]
        public T fooName { get; set; }
        [DataMember]
        public T fooAge { get; set; }
    }


We can use Foo<T> generic type in operation contract as follows:


        [OperationContract]
        Foo<string> GetFoo();

The service is implemented as follows:


 public Foo<string> GetFoo()
        {
            Foo<string> foo = new Foo<string>();
            foo.fooAge = "32";
            foo.fooName = "dj";
            return foo; 
        }

This is how you can create a service using generic types as Data Contract. However at the client side generic type will be not shown and data contract will be exposed with the name appended by type. So at the client side you will have FooOfString class as shown below:

image

We can consume the service created above as follows:


Service1Client proxy = new Service1Client();         
            FooOfstring foo = proxy.GetFoo();
            Console.WriteLine(foo.fooAge + foo.fooName);
            Console.ReadKey(true);


You will get expected output as shown below:

image

We learnt that the WCF supports exposing a generic type as DataContract.

Happy Coding.

Data Contract Serialization Events in WCF

In WCF we use the DataContract to serialize and deserialize the custom data. Sometime you may come across a scenario do some work before or after the data gets serialized or deserialized. These are following four events provided on the DataContract.

image

You are free to give any method name provided method should return void and takes StreamingContext as input parameter. In a block diagram we can show events sequence as follows:

image

You can create these events inside the class decorated with DataContract. Now let us see some real time examples. Let us say you have a DataContract as follows:

 


[DataContract]
    public class Product
    {
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public double Price { get; set; }
     }
}


We have a very simple ServiceContract defined as follows:

 


[ServiceContract]
    public interface IService1
    {

        [OperationContract]
        Product GetProduct(Product p);
      
    }


Service is implemented as follow which is basically echoing the data provided by the client.

 


public class Service1 : IService1
    {


        public Product GetProduct(Product p)
        {
            Product p1 = new Product { Name = p.Name, Price = p.Price };
            return p1; 
        }
    }


So far great now let is consume the service and examine the sequence of the serialization and deserialization events. Service is consumed as follows

 


Service1Client proxy = new Service1Client();
            Product p = new Product { Price = 300, Name = "Pen" };
            var result = proxy.GetProduct(p);
            Console.WriteLine(result.Name + result.Price);
            Console.ReadKey(true);


Now let us go ahead and modify the data contract class by adding the events. Modified class will look like as follows:

 


using System.Runtime.Serialization;

namespace DataContractEventsDemo
{
    [DataContract]
    public class Product
    {
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public double Price { get; set; }

        [OnSerializing]
        void OnSerializing(StreamingContext context)
        {

        }
        [OnSerialized]
        void OnSerialized(StreamingContext context)
        {

        }
        [OnDeserializing]
        void OnDeserializing(StreamingContext context)
        {

        }
        [OnDeserialized]
        void OnDeserialized(StreamingContext context)
        {

        }
    }
}

To find out sequence in which events get executed put a break point on the events. You will find events get executed in following sequence

image

Now consider a real time scenario that if client is not passing price of the product then service should provide a default price value. You can do that in OnDeserialized event as follows:

 

[OnDeserialized]
        void OnDeserialized(StreamingContext context)
        {
            if(Price==0)
            {
                Price = 99; 
            }
           
        }

Now if modify the client and not provide price as shown below

 


  static void Main(string[] args)
        {

            Service1Client proxy = new Service1Client();
            Product p = new Product { Name = "Pen" };
            var result = proxy.GetProduct(p);
            Console.WriteLine(result.Name + result.Price);
            Console.ReadKey(true);
        }

You will get output with default price as follows

clip_image002These events are useful to provide default values, closing connections to data base etc.Hope you find the post useful. Happy Coding.

Multiple bindings in self-hosted WCF Service

Even though WCF is now, more than 5 years old but still I see developers struggling with the multiple bindings specially when hosted in a managed console application. In this post, step by step we will learn to create a WCF Service with multiple bindings and host the service in a managed console application. We will do the following tasks in this post,

  • Create a service with the netTCPBinding
  • Host the service in a console application
  • Add wsHttpBinding EndPoint in the service
  • Consume the service in a client

To start with create a project by choosing either WCF Service Application or WCF Service Library from the WCF tab. I am selecting WCF Service Library project template.

clip_image002

Let us create a very simple service contract as follows


using System.ServiceModel;

namespace MultipleBindingSelfHosted
{
   
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        string GetData(int value);

        
    }

}


Next let us implement the service as follows:


namespace MultipleBindingSelfHosted
{
    public class Service1 : IService1
    {
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

       
    }
}


By this step we have created the service and implemented it. Compile the solution to make sure that everything is fine in the WCF project.

Now let us go ahead and add a console application in the project. This application will be the host application in which the service will be hosted. Let us follow the given steps:

  1. Create a console application in the project
  2. Add reference of System.ServiceModel
  3. Add reference of WCF project

Next in the App.config file of the console application we need to add service’s Endpoint configurations. Let us start with adding netTCPBinding Endpoint. To add the configuration follow the steps shown as follows:

  1. Add system.serviceModel
  2. Add services in the system.servicxeModel
  3. Add host base address in the host section
  4. Add Endpoint with netTcpBinding
  5. Add Metadata Endpoint for netTcpBinding

These steps can be done as shown below:

 

<system.serviceModel>

    <services>
      <service name="MultipleBindingSelfHosted.Service1" behaviorConfiguration="MultipleBindingSelfHostedBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:9002/MultipleBindingSelfHosted"/>
          </baseAddresses>
        </host>
        <endpoint address="net.tcp://localhost:9002/MultipleBindingSelfHosted"
                  binding="netTcpBinding" 
                  contract="MultipleBindingSelfHosted.IService1"/>
        <endpoint address="mex"
                  binding="mexTcpBinding" 
                  contract="IMetadataExchange"/>
      </service>
    </services>

  </system.serviceModel>


If you notice above we have added a service behaviour. So let us go ahead and configure the behaviour as follows:

 

<behaviors>
      <serviceBehaviors>
        <behavior name="MultipleBindingSelfHostedBehavior">
          <serviceMetadata httpGetEnabled="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

Great, by this step we have added Endpoint with the netTcpBinding. Next let us go ahead and create instance of the service host by passing service definition class in the constructor.


using System;
using System.ServiceModel; 

namespace MultipleBindingSelfHosted.Host
{
    class Program
    {
        static void Main(string[] args)
        {

            ServiceHost host = new ServiceHost(typeof(Service1));
            host.Open();
            Console.Write("Service is up and running");
            Console.WriteLine("To stop service press any key !!! ");
            Console.ReadKey();
            host.Close();

        }
    }
}


Press F5 to run the host application. You should see host application running as expected as follows:clip_image002[6]

Next we will go ahead and add an Endpoint for wsHttpBinding. To do this follows the steps as discussed follows:

  1. Add new base address
  2. Add new Endpoint with wsHttpBinding
  3. Give name to endpoints in case we may want to access separate Endpoint by providing Endpoint name the client

Add new base address as follows:

<add baseAddress="http://localhost:9001/MultipleBindingSelfHosted"/>

Add new Endpoint as follows. If you notice I have given name to the Endpoint as httpendpoint. You are free to give name of your choice.

<endpoint name="httpendpoint" address="http://localhost:9001/MultipleBindingSelfHosted" 
                  binding="wsHttpBinding" 
                  contract="MultipleBindingSelfHosted.IService1"/>


Also make sure that you have given a name to netTcpBinding Endpoint as well. Next let us go ahead and add metadata endpoint for http binding as well.

<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>

After configuring two Endpoints app.config of host application will look like as follows:


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <system.serviceModel>

    <services>
      <service name="MultipleBindingSelfHosted.Service1" behaviorConfiguration="MultipleBindingSelfHostedBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:9002/MultipleBindingSelfHosted"/>
            <add baseAddress="http://localhost:9001/MultipleBindingSelfHosted"/>
          </baseAddresses>
        </host>
        <endpoint address="net.tcp://localhost:9002/MultipleBindingSelfHosted"
                  binding="netTcpBinding" 
                  contract="MultipleBindingSelfHosted.IService1"/>
        <endpoint address="mex"
                  binding="mexTcpBinding" 
                  contract="IMetadataExchange"/>
        <endpoint name="httpendpoint" address="http://localhost:9001/MultipleBindingSelfHosted" 
                  binding="wsHttpBinding" 
                  contract="MultipleBindingSelfHosted.IService1"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MultipleBindingSelfHostedBehavior">
          <serviceMetadata httpGetEnabled="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

  </system.serviceModel>
</configuration>


Once again go ahead and build and run the application. You should able to get host application running as follows:

image

We have successfully created a self-hosted service with multiple Endpoint. Now let us go ahead and create a client to consume the service. In console application, right click and add service reference. If client is in the same solution then use Discover option else copy paste base address from app.config file of the hosted application.

image

And then you can call the service for two Endpoints as follows

// calling service with TCP binding 
            Service1Client tcpproxy = new Service1Client("tcpendpoint");
            var result1 = tcpproxy.GetData(12);
            Console.WriteLine(result1);

            //calling service with HTTP binding 
            Service1Client httpproxy = new Service1Client("httpendpoint");
            var result2 = httpproxy.GetData(12);
            Console.WriteLine(result2);

            Console.ReadKey(true);


In this way you can create the self-hosted WCF service with multiple Endpoints. I hope this post is useful. Happy Coding!

Fault Contract’1 was unhandled by user code: Solved

For a training purpose I was trying a basic demo on fault contract in WCF and to be surprised I Got below error while throwing FaultException.

clip_image002

It’s not that 1st time I was working on Fault Contract but this error was irritating. After some investigation I found there was some issue in visual studio 2013 setting. So to solve this in Visual Studio go to Tools->Options.

In General tab from Debugging section uncheck following options,

  • Enable the exception assistant
  • Enable Just My Code
  • image

    Changes in Visual Studio setting should solve the problem. Keep in mind that above error can occur due to other reasons also. Visual setting debugging option may be one way to solve above said error. I hope you find it useful. Thanks for reading.

    Publish WCF Service in Local IIS on Visual Studio 2013

    Long back I wrote a blog post Step by Step hosting WCF Service in IIS 7.5 . In this post I used Visual Studio 2012 as I remember. Today I was trying to host WCF in local IIS in Visual Studio 2013 and found it is surprisingly easy to host WCF Service in IIS 2013 in Visual Studio 2013.

    Let us assume you have created a WCF Service. Now to publish it in local IIS right click on project and from context menu select Properties.

    In Properties select Web tab. In Web tab from Servers drop down select local IIS.

    clip_image002

    Next click on Package/Publish Web tab and from Items to deploy drop down select Only Files Needed to run this application.

    clip_image004

    Now when you press F5 and run application WCF Service will be hosted in local IIS.

    clip_image006

    As you see now hosting in IIS is super easy. I hope you find this post useful. Thanks for reading.

    Solved Access-Control-Allow-Origin Error in WCF REST Service

     

    Recently I was working on a JSON based WCF REST Service. It was a simple service performing CRUD operation. When I tried to consume service from a web based client, got following errors in browser console.

    clip_image002

    Error message was, No Access-Control-Allow-Origin header is present on the required resource. Since service was running on different server and it was not configured to accept request from any origin. This error can be resolved by enabling CORS: Cross Origin Resource Sharing for the service.

    image

    You can enable CORS on service hosted on IIS or IIS Express by adding following configuration in config file.

    clip_image002[6]

    We have added a custom header that allow Access-Control-Allow-Origin value to *. By setting it * , we are allowing request from any origin to access the service. So to solve error I went ahead and added following configuration in web.config of service under system.webServer section,

    
    <system.webServer>
        
        <httpProtocol>
          <customHeaders>
            <add name="Access-Control-Allow-Origin" value="*" />
          </customHeaders>
        </httpProtocol>    
        
        <modules runAllManagedModulesForAllRequests="true"/>  
        <directoryBrowse enabled="true"/>
      </system.webServer>
    
    
    

     

    After adding above configuration you should able to access service in client side codes like JavaScript. I hope this post is useful.

    Dealing Multiple EndPoints of a WCF Service

    If you know EndPoints well, you know WCF well. Configuring EndPoints are vital for any WCF design. You can configure EndPoints either via code or in web.config file. I have seen many times, developers are confused with EndPoints. I have come across following common question about EndPoints

    • Can we have multiple EndPoints?
    • Can be expose same contracts on more than one EndPoint?
    • How base address works with EndPoints?
    • Can we have more than one base address?
    • How to configure EndPoint in code?
    • Do we need to configure EndPoint in self hosting?
    • Can we have more than one Service Contract?

    And many more questions of such like above.

    To answer above questions, let us start with understanding what is EndPoint?

    Endpoint identifies a WCF Service. EndPoint is combination of Address, Contract and Binding. Mathematically EndPoint can be defined as below,

    image

    Where A, B and C are as follows,

    image

    Now it is simple mathematical addition rule that if we change any of A, B or C value then we will get new E. So for any reason if you change either of Address, Contract or Binding then a new EndPoint will get created. You may have multiple EndPoints of same service

    • If same Service hosted on Multiple Address with same Binding and same Contract
    • If same Service with different Contract on same Address and for same Binding
    • If same Service with different Bindings on same Address and for same Contract.

    We can say,

    image

    As a Service designer you may consider to create multiple EndPoints in following scenarios.

    • Service wants to expose more than one type of binding.
    • Service wants to expose more than one contract on the same binding.
    • Service wants to expose same binding and contract on different addresses.

    Multiple Binding Scenario

    Now let us see how we can expose a Service on two different bindings using multiple EndPoints. For two different bindings, we will create two different EndPoints.

    Let us say we have a service as below,

    
    public interface IService1
        {
            [OperationContract]
            string  message(string name);        
    
        }
    
    

    And Service is implemented as below,

    
    public class Service1 : IService1
        {
            public string message(string name)
            {
                return "Hello " + name;
            }
        }
    
    

    We can configure multiple EndPoints as,

    
    <service name="MessagePatternDemo.Service1">
            <endpoint name="ep1"
                      address="/ep1"
                      binding="basicHttpBinding"
                contract="MessagePatternDemo.IService1"/>
            <endpoint  name="ep2"
                       address="/ep2"
                       binding="wsHttpBinding"
            contract="MessagePatternDemo.IService1"       />
            <endpoint name="mex"
                      contract="IMetadataExchange"
                      address="mex"
                      binding="mexHttpBinding" />
          </service>      
    
    

    In above configuration we are creating two EndPoints for the same service. Same Service is exposed on different bindings. Client can access same service either on basicHttpBinding or wsHttpBinding. Both EndPoints are identified with different names like ep1 and ep2. In multiple EndPoints each EndPoint will be exposed on different address with different names

    At client side same service can be consumed by passing EndPoint name.

    
    Service1Client proxy1 = new Service1Client("ep1");
                var message = proxy1.message("dj");
                Console.WriteLine(message);
                Console.ReadKey(true);
    
    

    We are passing ep1 as name of the EndPoint, so client will consume service using basicHttpBinding. If you do not pass EndPoint name at time of proxy creation then run time error will get occur while calling service.

    In above scenario, we exposed same service on multiple bindings using two different EndPoints.

    Multiple Address Scenario

    There could be scenario when you may want to expose same service on multiple base address. You can have more than one base address in service. Base address is created under host as below,

    image

    You can add more than one base address using add in baseAddresses section.Advantage of having base address is that, if we are moving service from one server to another then only base address need to be changed and all EndPoint will work on updated server. WCF allow us to give multiple base addresses for each type of protocol. And at the run time corresponding endpoint will take the base address.

    image

    So you can expose IService1 on multiple EndPoint with more than one binding as below. We are exposing IService1 with basicHttpBinding and netTcpBinding both. At the run time WCF will attach corresponding base address to respective binding.

    
    <services>
          <service name="MessagePatternDemo.Service1">
            <endpoint name="ep1"
                      address="/ep1"
                      binding="basicHttpBinding"
                contract="MessagePatternDemo.IService1"/>
            <endpoint  name="ep2"
                       address="/ep2"
                       binding="netTcpBinding"
            contract="MessagePatternDemo.IService1"/>
            <endpoint
                      contract="IMetadataExchange"
                      address="mex"
                      binding="mexHttpBinding" />
                    <endpoint address="mex1"
                      binding="mexTcpBinding"
                      contract="IMetadataExchange"/>        
    
          <host>
            <baseAddresses>
              <add baseAddress="http://localhost:8081"/>
              <add baseAddress="net.tcp://localhost:8082"/>
            </baseAddresses>
          </host>
          </service>      
    
        </services>
    
    

    You may want to host same service on different server, in that scenario also service will have same contract and binding whereas different address.

    Multiple Contract Scenario

    There could be scenario when you will have to expose multiple Service Contracts. Service Contracts will be exposed on separate EndPoints.

     

    image

    Let us say we have two services IService1 and IService2 as below,

    
    [ServiceContract]
        public interface IService1
        {
            [OperationContract]
            string  messagefromservice1(string name);        
    
        }
    
        [ServiceContract]
        public interface IService2
        {
            [OperationContract]
            string messagefromservice2(string name);
    
        }
    
    

    And Service is implemented as below,

    
      public class Service1 : IService1, IService2
        {
            public string messagefromservice2(string name)
            {
                return "Hello " + name + "  from service1";
            }
    
            public string messagefromservice1(string name)
            {
                return "Hello " + name + "  from service2";
            }
        }
    
    

    In config file we have created multiple EndPoints exposing IService1 and IService2 as below,

    
    <services>
          <service name="MessagePatternDemo.Service1">
    
            <endpoint name="ep1"
                      address="/ep1"
                      binding="basicHttpBinding"
                contract="MessagePatternDemo.IService1"/>
    
            <endpoint  name="ep2"
                       address="/ep2"
                       binding="basicHttpBinding"
            contract="MessagePatternDemo.IService2"/>
    
            <endpoint
                      contract="IMetadataExchange"
                      address="mex"
                      binding="mexHttpBinding" />
    
          <host>
            <baseAddresses>
              <add baseAddress="http://localhost:8081"/>
            </baseAddresses>
          </host>
          </service>      
    
        </services>
    
    

    At client side while consuming service you will get information that there are two service contracts as part of the service. As you see in Add Service Reference dialog that there are two services listed and they are IService1 and IService2

    clip_image002

    To use these service you will have to create separate proxies. Both services can be consumed at client as below,

    
    Service1Client proxy1 = new Service1Client();
                var message = proxy1.messagefromservice1("dj");
                Console.WriteLine(message);
    
                Service2Client proxy2 = new Service2Client();
                var message1 = proxy2.messagefromservice2("dj");
                Console.WriteLine(message1);   
    
                Console.ReadKey(true);
    
    

    On running you will get output as below,

    image

    Having multiple EndPoints for services are sometime essential for a good service design. You may want to expose same service on different EndPoint for Internet user whereas for Intranet user on separate EndPoint. I hope this post is useful for you.