Enumeration in DataContract of WCF

By default Enums are serializable. If we define Enum at service side and use it in Data Contract, it is exposed at the client side.

For example, if we have an Enum as below,

clip_image001[1]

And we are using it in DataContract as below

clip_image003[1]

By default Enum is serialized.

So, let us see the default behavior of Enum with an example.

1. Create a DataContract called Product.

Product.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization;

namespace WcfService1
{
    [DataContract]
    public class Product
    {
        [DataMember]
       public  string ProductName;
        [DataMember]
       public  ProductDeliveryPriority ProductPriority;
       
    }
     public  enum ProductDeliveryPriority
    {
             Low,     
        Normal,
              High,
               Urgent

    }
}

2. Create the Service Contract. We are just returning a Product from the service.

IService1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace WcfService1
{
  [ServiceContract ]
    public  interface IService1
    {

      [OperationContract]
      Product GetProduct();
    
    }
}

 

3. Implement the service in service definition .

Service1.svc.cs

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WcfService1
{
   
    public class Service1 : IService1 
    {
        public Product GetProduct()
        {
            Product p = new Product { ProductName = "Pen", ProductPriority = ProductDeliveryPriority.Normal };
            return p;            
                       
        }  
       
    }
}

4. Define the EndPoint in config file as below. We are exposing the service with basicHttpBinding. 

Web.Config

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service name ="WcfService1.Service1" >
        <endpoint address ="" binding ="basicHttpBinding" contract ="WcfService1.IService1"/>
        <endpoint address ="mex" binding ="mexHttpBinding" contract ="IMetadataExchange"/>
        <host>
          <baseAddresses>
            <add baseAddress ="<a href="http://localhost:8181/Service1.svc&quot;/">http://localhost:8181/Service1.svc"/</a>>
          </baseAddresses>
        </host>
      </service>     
    </services>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
 
</configuration>

5. Test the service in browser

clip_image005[1]

6. Consume the service at the client. Add the service reference at the client side and create the proxy.

Program.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using ConsoleApplication1.ServiceReference1;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
          
                Service1Client proxy = new Service1Client();
                Product p = proxy.GetProduct();
                Console.WriteLine(p.ProductName);
                Console.WriteLine(p.ProductPriority.ToString());
           
            Console.ReadKey(true);
        }
           
    }
}

We added the service reference and namespace. On running the output we will get is

clip_image007[1]

Excluding certain ENUM values

If we want to exclude certain member from ENUM then we need to follow below steps

1. Decorate the Enum with DataContract attribute

clip_image008[1]

2. Decorate the entire member we want to expose to client as EnumMember. Any Enum member not decorated with EnumMember will not be exposed to the client.

clip_image009[1]

In above Enum definition we are not decorating Normal with EnumMember . and in service we are returning Normal to the client . so when client will try to access normal enum value , it will throw an error.

So let us modify the Enum as below,

Modified Enum definition

[DataContract]
   public  enum ProductDeliveryPriority
    {
       [EnumMember]
       Low,     
        Normal,
       [EnumMember]
        High,
        [EnumMember]
        Urgent

    }

And at the client side while accessing

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using ConsoleApplication1.ServiceReference1;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Service1Client proxy = new Service1Client();
                Product p = proxy.GetProduct();
                Console.WriteLine(p.ProductName);
                Console.WriteLine(p.ProductPriority.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.ReadKey(true);
        }
           
    }
}

Output

clip_image011[1] 

We are getting this error at client side because in service we are retuning a Product with ProductPriority normal but normal is not attributed with EnumMember. So it is not exposed on wire or serialized.

2 responses to “Enumeration in DataContract of WCF”

  1. Do not expose enum in wcf response for backward compatibility reasons.
    See http://stackoverflow.com/a/788281/52277

  2. ​Do not expose enum in wcf response for backward compatibility reasons.
    ​See http://stackoverflow.com/a/788281/52277

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create a website or blog at WordPress.com