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.