SIGN UP MEMBER LOGIN:    
ARTICLE

Enumeration in DataContract of WCF

Posted by Dhananjay Kumar Articles | C# Language November 01, 2010
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.
Reader Level:

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.  

Login to add your contents and source code to this article
share this article :
post comment
 

Hi, nice post, but be aware that you can run into serious problems if your enumeration does not start with 0 (e.g. [DataContract] public enum ProductDeliveryPriority { [EnumMember] Low = 1, Norma = 4l, [EnumMember] High = 8, [EnumMember] Urgent = 16 } I got some problems with deserialization (a pitty I do not remember the exact exception thrown)...but keep that in mind. Kind regards, Harry

Posted by Harry Feb 17, 2011

Dhananjay. Nice one. Simple and well written steps. Easy to Follow.

Posted by Sivaraman Dhamodaran Nov 01, 2010
Become a Sponsor
PREMIUM SPONSORS
  • ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications. Visit DynamicPDF here
    The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
6 Months Free & No Setup Fees ASP.NET Hosting!
Become a Sponsor