Versioning in WCF Data Contract: Part II - Missing Members


Part #1 of the article can be read here.

If we have a DataContract 

Product.cs

[DataContract]
    public class Product
    {
        [DataMember(Order = 1)]
        public string ProductNumber;
        [DataMember(Order = 2)]
        public string ProductName;
        [DataMember(Order = 3)]
        public string ProductPrice;
        [DataMember(Order = 4)]
        public string ProductColor;
    }  

ServiceContract is as below 

IService1.cs

namespace WcfService10
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        Product  GetaProduct(Product p );
    }
}

And Service implementation is as below, 

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 WcfService10
{  
    public class Service1 : IService1
    {
      public Product GetaProduct(Product p)
      {
          Product p1 = new Product
          {
              ProductNumber = p.ProductNumber,
              ProductName = p.ProductName,
              ProductPrice = p.ProductPrice,
              ProductColor = p.ProductColor
          };
          return p1;
        }
    }
}

Now we have a service. 

Now at the client side (Say it as client1) we are calling the service as below 

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleApplication1.ServiceReference1;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            using (Service1Client proxy = new Service1Client())
            {
                Product p = new Product{ProductNumber="1",
                                        ProductPrice="100",
                                        ProductName ="Bat",
                                        ProductColor ="White"};
                var res = proxy.GetaProduct(p);
                Console.WriteLine(res.ProductName+"\n" + res.ProductPrice+"\n" + res.ProductNumber+"\n"+res.ProductColor);
            }
            Console.ReadKey(true);
        }
    }
}

Output 

1.gif
 
Now let us go ahead and modify the service implementation as below, 

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 WcfService10
{  
    public class Service1 : IService1
    {
      public Product GetaProduct(Product p)
      {
          Product p1 = new Product
          {
              ProductNumber = p.ProductNumber??"Missing Number",
              ProductName = p.ProductName??"Missing Name",
              ProductPrice = p.ProductPrice??"Missing Price",
              ProductColor = p.ProductColor??"Missing color"
          };
          return p1;
        }
    }
}

If you see the above implementation , we are assigning some default value when value of  the property is not provided or in other words Members are missing. 

ProductNumber = p.ProductNumber??"Missing Number",
ProductName = p.ProductName??"Missing Name",
ProductPrice = p.ProductPrice??"Missing Price",
ProductColor = p.ProductColor??"Missing color"

So if at the client side DataContract, some DataMember is missing. In this case at the client side member ProductColor is missing 

Product p = new Product{ProductNumber="1",
                        ProductPrice="100",
                        ProductName ="Bat"};

Now at the service side one DataMember is missing so Service implementation will return default value for that

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleApplication1.ServiceReference1;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            using (Service1Client proxy = new Service1Client())
            {
                Product p = new Product{ProductNumber="1",
                                        ProductPrice="100",
                                        ProductName ="Bat"};
                var res = proxy.GetaProduct(p);
                Console.WriteLine(res.ProductName+"\n" + res.ProductPrice+"\n" + res.ProductNumber+"\n"+res.ProductColor);
            }
            Console.ReadKey(true);
        }
    }
}

Output 

2.gif

OnDeserializing event 

In case of missing DataMember , we can use OnDeserializing event to share the logic across all the party 

Product.cs

[DataContract]
    public class Product
    {
        [DataMember(Order = 1)]
        public string ProductNumber;
        [DataMember(Order = 2)]
        public string ProductName;
        [DataMember(Order = 3)]
        public string ProductPrice;
        [DataMember(Order = 4)]
        public string ProductColor;
        [OnDeserializing]
        void OnDeserializing(StreamingContext context)
        {
            ProductName = "Name Missing";
            ProductNumber = "Number Missing";
            ProductColor = "Color Missing ";
            ProductPrice = "Price Missing";
        }
    }

Up Next
    Ebook Download
    View all
    Learn
    View all