WCF DataContract with enum example


WCF DataContracts

This article explains required steps to implement WCF DataContracts with Enum members. DataContract represents the business entities like Product, Customer, Order. It is a agreement between service and clients for exchanging data.

Go through an article on WCF DataContract attributes for the best use of DataContracts.


Step by step implementation of WCF DataContract and Enum members


  1. Create WCF Service Library

    Create a WCF service library as suggested in Create new WCF service library and test using WCFTestClient.

  2. Add ProductWebOnly DataContract enum

    Add ProductWebOnly enum to the WCF Service Library created in previous step. Right click on NorthwindServices -> Select Add -> Class -> name it as ProductWebOnly.cs.

    Add Enum Members to it as Yes and No to indicating whether the project is avilable only on Web.

                    
        using System.Runtime.Serialization;
    
        namespace NorthwindServices
        {
            [DataContract]
            public enum ProductWebOnly
            {
                [EnumMember] 
                Yes,
    
                [EnumMember]
                No
            }
        }
                
  3. Product datastore

    Create or replace Products.xml for service data store. Add below xml to the file.

    Note that XML is different than the one created in first step. Added new WebOnly element for ProductWebOnly enum

                    
    <?xml version="1.0" standalone="yes"?>
    <DocumentElement>
      <Products>
        <ProductID>1</ProductID>
        <ProductName>Chai</ProductName>
        <categoryID>1</categoryID>
        <UnitsInStock>39</UnitsInStock>
        <CategoryName>Condiments</CategoryName>
        <WebOnly>Yes</WebOnly>
      </Products>
      <Products>
        <ProductID>2</ProductID>
        <ProductName>Chang</ProductName>
        <categoryID>1</categoryID>
        <UnitsInStock>17</UnitsInStock>
        <CategoryName>Condiments</CategoryName>
        <WebOnly>No</WebOnly>
      </Products>
      <Products>
        <ProductID>3</ProductID>
        <ProductName>Aniseed Syrup</ProductName>
        <categoryID>2</categoryID>
        <UnitsInStock>13</UnitsInStock>
        <CategoryName>Condiments</CategoryName>
        <WebOnly>Yes</WebOnly>
      </Products>  
    </DocumentElement>
                        
                
  4. Add Product DataContract

    Add Product DataContract to the WCF Service Library created in previous step. Right click on NorthwindServices -> Select Add -> Class -> name it as Product.cs

    Product DataContract will represent Product entity from Products.xml datastore.

    See the use of WebOnly DataMember which is using ProductWebOnly DataContract.

                    
    using System.Runtime.Serialization;
    
    namespace NorthwindServices
    {
    [DataContract]
    public class Product
    {
        [DataMember]
        public int ProductID { get; set; }
    
        [DataMember] 
        public string ProductName { get; set; }
    
        [DataMember] 
        public int CategoryID { get; set; }
    
        [DataMember] 
        public string CategoryName { get; set; }
    
        [DataMember] 
        public int UnitsInStock { get; set; }
    
        [DataMember] 
        public ProductWebOnly  WebOnly { get; set; }
    }
    }               
                
  5. New OperationContract

    Open IProducts ServiceContract from NorthwindServices library and add new OperationContract GetProducts, GetAllProducts, AddProduct.

                    
    using System.ServiceModel;
    
    namespace NorthwindServices
    {
    [ServiceContract]
    public interface IProducts
    {
        [OperationContract] 
        string GetProductName(int productID);
    
        [OperationContract]
        int GetProductQty(int productID);
    
        [OperationContract]
        string GetCategoryName(int productID);
                
        [OperationContract] Product GetProduct(int productID); 
            
        [OperationContract] 
        List<Product> GetAllProducts(); 
            
        [OperationContract] 
        bool AddProduct(Product product);
    }
    }               
                
  6. Implementation IProducts ServiceContract

    Implement the IProducts ServiceContract by implementing its OperationContracts. Open the ProductService.cs file created in first step from NorthwindServices. Add new methods for OperationContract GetProduct, GetAllProducts, AddProduct.

    The method implementaion of GetCategoryName, GetProductQty, GetProductName created in first step has omitted from below code as it does not implement DataContract. You should keep it in ProductService.cs or remove it from IProduct.cs as well.

                    
    using System.Xml.Linq;
    
    namespace NorthwindServices
    {
        public class ProductService : IProducts 
        {
            public Product GetProduct(int productID)
            {
                Product product = new Product();
    
                XDocument doc = XDocument.Load("C:\\products.xml");
    
                IEnumerable<XElement> products =
                    (from result in doc.Descendants("DocumentElement")
                        .Descendants("Products")
                        where result.Element("ProductID").Value==productID.ToString()
                        select result);
    
                product.ProductID = 
                        products.ElementAt(0).Element("ProductID").Value;
                product.ProductName = 
                        products.ElementAt(0).Element("ProductName").Value;
                product.CategoryID = 
                        products.ElementAt(0).Element("categoryID").Value;
                product.UnitsInStock = 
                        products.ElementAt(0).Element("UnitsInStock").Value;
                product.WebOnly = 
                        (ProductWebOnly)Enum.Parse(typeof(ProductWebOnly), 
                                    products.ElementAt(0).Element("WebOnly").Value);   
    
                return product; 
            }
    
            public List<Product> GetAllProducts()
            {
                List<Product> lstProducts = new List<Product>();
    
                XDocument doc = XDocument.Load("C:\\products.xml");
    
                IEnumerable<XElement> products =
                    (from result in doc.Descendants("DocumentElement")
                        .Descendants("Products")
                        select result);
    
                foreach(XElement element in products)
                {
                   Product product = new Product();
    
                   product.ProductID = element.Element("ProductID").Value;
                   product.ProductName = element.Element("ProductName").Value;
                   product.CategoryID = element.Element("categoryID").Value;
                   product.UnitsInStock = element.Element("UnitsInStock").Value;
                   product.WebOnly=(ProductWebOnly)Enum.Parse(
                         typeof(ProductWebOnly), element.Element("WebOnly").Value);
                   lstProducts.Add(product);
                }
                return lstProducts; 
            }
    
            public bool AddProduct(Product product)
            {
                List<Product> lstProducts = new List<Product>();
    
                XDocument doc = XDocument.Load("C:\\products.xml");
    
                doc.Element("DocumentElement").Add(
                        new XElement("Products",
                        new XElement("ProductID", product.ProductID),
                        new XElement("ProductName", product.ProductName),
                        new XElement("UnitsInStock", product.UnitsInStock),
                        new XElement("CategoryID", product.CategoryID),
                        new XElement("CategoryName", product.CategoryName),
                        new XElement("WebOnly", product.WebOnly)));
    
                doc.Save("C:\\products.xml");  
    
                return true;
            }
        }
    }               
                

    If you provide an input value to parameter ProductID of GetProduct method which is not available in data store. It will through an exception. So handle such exceptions using FaultContract.

  7. ProductService Endpoint

    You do not need to change anything from app.config file for service endpoint as you have just added some methods to ServiceContract and do not have change address, binding or contract.

    Make sure you have below endpoint in app.config of Service library.

                    
        <service name="NorthwindServices.ProductService">
        <host>
            <baseAddresses>
            <add baseAddress = 
                   "http://localhost:7741/NorthwindServices/ProductService" />
            </baseAddresses>
        </host>
        <endpoint address ="" binding="wsHttpBinding" 
                    contract="NorthwindServices.IProducts">
            <identity>
            <dns value="localhost"/>
            </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" 
                        contract="IMetadataExchange"/>
        </service>
                        
                
  8. Host Product WCF Service

    Host this Product WCF Service in IIS using WCF service in IIS or in Windows service.

  9. Client Application for Product WCF service

    Open the program.cs file from Client application created in previous step. Add implementation for Service Operations.

                    
    using NorthwindApp.ProductServiceRef;  
    
    namespace NorthwindApp
    {
        class Program
        {
            static void Main(string[] args)
            {
                AddProduct(); 
                GetAllProducts(); 
                GetProductDetails(); 
                Console.Read();  
            }
    
            private static void AddProduct()
            {
                using (ProductsClient client = new ProductsClient())
                {
                    Product product = new Product();
                    product.CategoryID = "2";
                    product.CategoryName = "Condiments";
                    product.ProductID = "8";
                    product.ProductName = "Coffee";
                    product.UnitsInStock = "20";
                    product.WebOnly = ProductWebOnly.No;
                    client.AddProduct(product);  
                }
            }
    
            private static void GetAllProducts()
            {
                using (ProductsClient client = new ProductsClient())
                {
                    Product[] products =  client.GetAllProducts();
    
                    for (int index = 0; index < products.Count(); index++)
                    {
                        ShowProduct(products[index]);
                    }
                }
            }
    
            private static void GetProductDetails()
            {
                using (ProductsClient client = new ProductsClient())
                {
                    ProductServiceRef.Product product = client.GetProduct(2);
                    ShowProduct(product);  
                }
            }
    
            private static void ShowProduct(Product product)
            {
                Console.WriteLine("Product ID : " + product.ProductID);
                Console.WriteLine("Product Name : " + product.ProductName);
                Console.WriteLine("CategoryID : " + product.CategoryID);
                Console.WriteLine("Units In Stock : " + product.UnitsInStock);
                Console.WriteLine("Web Only : " + product.WebOnly);
                Console.WriteLine("********************************");
                Console.WriteLine(); 
            }
        }
    }
                

Download source code.

Speak your mind :
Leave a comment for this article on dotnetbloogers.com