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, 

1.gif
 
And we are using it in DataContract as below 

2.gif
 
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 ="http://localhost:8181/Service1.svc"/>
              </baseAddresses>
            </host>
          </service>     
        </services>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
      </system.serviceModel>
     <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
      </system.webServer>
    </configuration>

  5. Test the service in browser 

    3.gif

  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

4.gif
 
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 

    5.gif
  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. 

    6.gif
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

7.gif
 
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.  

Up Next
    Ebook Download
    View all
    Learn
    View all