Search code examples
c#wcf

Object deserialization problem between two different DataContracts


In my solution architecture, I am following: enter image description here

I have an object deserialization problem. I am getting the following exception on my client app during the deserialization process.

{"Unable to deserialize XML body with root name 'User' and root namespace 'http://schemas.datacontract.org/2004/07/ECMS.Business.Entities' (for operation 'Login' and contract ('ISecurityService', 'http://tempuri.org/')) using DataContractSerializer. Ensure that the type corresponding to the XML is added to the known types collection of the service."}

In the ECMS.Business.Entities project I have the following entity

[DataContract]
public class User : IIdentifiableEntity
{
    [DataMember]
    public int Id { get; set; }
    public int EntityId
    {
        get => Id;
        set => Id = value;
    }
    [DataMember]
    public string UserName { get; set; }
    [DataMember]
    public string FullName { get; set; }
    public string Password { get; set; }
    [DataMember]
    public int Role { get; set; }
    public bool IsActive { get; set; }

    public ICollection<UserSession> Sessions { get; set; }
    public ICollection<Visit> Visits { get; set; }
}

Which I need to return back to the client side (ECMS.Client.Entities project) as the following entity

[DataContract]
public class User : ObjectBase
{
    private int _id;

    [DataMember]
    public int Id
    {
        get => _id;
        set
        {
            if (_id != value)
            {
                _id = value;
                OnPropertyChanged();
            }
        }
    }

    private string _userName;

    [DataMember]
    public string UserName
    {
        get => _userName;
        set
        {

            if (_userName != value)
            {
                _userName = value;
                OnPropertyChanged();
            }
        }
    }

    private string _fullName;

    [DataMember]
    public string FullName
    {
        get => _fullName;
        set
        {
            if (_fullName != value)
            {
                _fullName = value;
                OnPropertyChanged();
            }
        }
    }

    private int _role;
    [DataMember]
    public int Role
    {
        get => _role;
        set
        {
            if (_role != value)
            {
                _role = value;
                OnPropertyChanged();
            }
        }
    }
}

[DataContract]
public abstract class ObjectBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Solution

  • DataContact namespaces have to match when using separate server and client contracts!

    From here:

    For data contracts to be equivalent, they must have the same namespace and name