Friday 3 July 2015

Match data contract namespaces in two entities

When we need to do any data contract mapping between two layers or entities ( eg : client and server sides ) the name spaces should match. Otherwise the mismatch error would occur when we tying to do the data contact mapping in between two layers or entities.

Following are the two example data contract classes that resides in two layers.

The Business Entity data contract class

namespace TestApp.Business.Entities
{
    [DataContract]
    public class Student : EntityBase, IIdentifiableEntity
    {
        [DataMember]
        public int StudentId { get; set; }

        [DataMember]
        public string Name { get; set; }

        [DataMember]
        public int Age{ get; set; }
   }
}
The Business Client entity data contract class
namespace TestApp.Client.Entities
{
    [DataContract]
    public class Student : EntityBase, IIdentifiableEntity
    {
        [DataMember]
        public int StudentId { get; set; }

        [DataMember]
        public string Name { get; set; }

        [DataMember]
        public int Age{ get; set; }
   }
}


This would give the m=contract mismatch error because the name spaces are different. The simplest solution for this is having the namespace tag in the contract attribute.
namespace TestApp.Business.Entities
{
     [DataContract(Namespace = "http://www.priyaltech.com/appname/servicename")]
    public class Student : EntityBase, IIdentifiableEntity
    {
        [DataMember]
        public int StudentId { get; set; }

        [DataMember]
        public string Name { get; set; }

        [DataMember]
        public int Age{ get; set; }
   }
}

namespace TestApp.Client.Entities
{
    [DataContract(Namespace = "http://www.priyaltech.com/appname/servicename")]
    public class Student : EntityBase, IIdentifiableEntity
    {
        [DataMember]
        public int StudentId { get; set; }

        [DataMember]
        public string Name { get; set; }

        [DataMember]
        public int Age{ get; set; }
   }
}

But most of the time in the client side, we tend to not to have simple public attributes with data contracts. This is mainly due to the validation and and other client side processing we need to do. Typical client side data entity class would looks like following.
namespace CarRental.Client.Entities
{
    public class Student: ObjectBase
    {
        int _StudentId;
        string _Name ; 
        int _Age;

        public int StudentId
        {
            get { return _StudentId; }
            set
            {
                if (_StudentId != value)
                {
                    _StudentId = value;
                    OnPropertyChanged(() => StudentId);
                }
            }
        }

        public string Name
        {
            get { return _Name; }
            set
            {
                if (_Name != value)
                {
                    _Name = value;
                    OnPropertyChanged(() => Name);
                }
            }
        }

      public int Age
        {
            get { return _Age; }
            set
            {
                if (_Age != value)
                {
                    _Age = value;
                    OnPropertyChanged(() => Age);
                }
            }
        }
   }
}

As you can see, we do not have the DataContract and DataMember attributes in this client class. So how we can do the contract mapping. The best way is to use the AssemblyInfo class of the project and do the data contract mapping there as follows.
[assembly: ContractNamespace("http://www.priyaltech.com/appname/servicename",
                              ClrNamespace = "TestApp.Business.Entities")]
Do the same to the client project's AssemblyInfo class as well.
[assembly: ContractNamespace("http://www.priyaltech.com/appname/servicename",
                              ClrNamespace = "TestApp.Client.Entities")]


No comments:

Post a Comment