Ask a questionAsk a question
 

AnswerWCF, Silverlight and inheritance/polymorfism

  • Saturday, November 07, 2009 12:38 AMKrikke999 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Hi,

    I have a WCF service that exposes a method GetEmployees.
    The data contracts are:

    public interface IEmployee
        {
            string Id { get; set; }
    
            string Requestor { get; set; }
            string Executive { get; set; }
            string Senior { get; set; }
            CellData Country { get; set; }
            List<CostCenterItem> CostCenter { get; set; }
            BenefitsItem Benefits { get; set; }
            int HoursPerWeek { get; set; }
            string ReasonForRecruitment { get; set; }
            string ProfileDemands { get; set; }
            EmployeeType EmployeeType { get; set; }
        }
    
     [DataContract]
        [KnownType(typeof (Intern))]
        [KnownType(typeof (Employee))]
        [KnownType(typeof (Freelancer))]
        [KnownType(typeof (BenefitsItem))]
        [KnownType(typeof (ContractItem))]
        [KnownType(typeof (CostCenterItem))]
        [KnownType(typeof (Shared.Contract))]
        [KnownType(typeof (EmployeeType))]
        public abstract class ConcreteEmployee : IEmployee
        {
            #region IEmployee Members
    
            [DataMember]
            public string Id { get; set; }
    
            [DataMember]
            public string Requestor { get; set; }
    
            [DataMember]
            public string Executive { get; set; }
    
            [DataMember]
            public string Senior { get; set; }
    
            [DataMember]
            public CellData Country { get; set; }
    
            [DataMember]
            public List<CostCenterItem> CostCenter { get; set; }
    
            [DataMember]
            public BenefitsItem Benefits { get; set; }
    
            [DataMember]
            public int HoursPerWeek { get; set; }
    
            [DataMember]
            public string ReasonForRecruitment { get; set; }
    
            [DataMember]
            public string ProfileDemands { get; set; }
    
            [DataMember]
            public EmployeeType EmployeeType { get; set; }
    
            #endregion
        }
    
     [DataContract]
        public class Employee : ConcreteEmployee
        {
            #region Ctors
    
            public Employee()
            {
                // Set Employee type to the object --> one grid with all objects (Employees, Interns and Freelancers)
                EmployeeType = EmployeeType.Employee;
            }
    
            public static Employee Construct()
            {
                return new Employee();
            }
    
            #endregion
    
            #region Properties
    
            public string Evaluator { get; set; }
    
            public string LeaveApprover { get; set; }
    
            public string Channel { get; set; }
    
            public string Gepland { get; set; }
    
            public string Function { get; set; }
    
            public string FuntionInitial { get; set; }
    
            public string Type { get; set; }
    
            public DateTime PreferedStartDate { get; set; }
    
            public ContractItem ContractItem { get; set; }
    
            public string ReqruitementVia { get; set; }
    
            #endregion
        }
    
     [DataContract]
        public class Freelancer : ConcreteEmployee
        {
            #region Public Properties
    
            public Freelancer()
            {
                EmployeeType = EmployeeType.Freelance;
            }
    
            public DateTime StartDate { get; set; }
    
            public DateTime EndDate { get; set; }
    
            #endregion
    
            #region Ctor
    
            public static Freelancer Construct()
            {
                return new Freelancer();
            }
    
            #endregion
        }
    
    
    
    service:

     [ServiceContract]
        public interface IEmployeeService
        {
            [OperationContract(AsyncPattern = true)]
            [FaultContract(typeof(FaultDetail))]
            IAsyncResult BeginGetAllVacancies(AsyncCallback callback, Object state);
            List<ConcreteEmployee> EndGetAllVacancies(IAsyncResult result);
        }
    
     public class EmployeeService : IEmployeeService
        {
            #region Implementation of IEmployeeService
    
            public IAsyncResult BeginGetAllVacancies(AsyncCallback callback, object state)
            {
                List<ConcreteEmployee> employees = new GlobalData().GetData();
                var asyncResult = new AsyncResult<List<ConcreteEmployee>>(employees, callback, state);
                callback.Invoke(asyncResult);
                return asyncResult;
            }
    
            public List<ConcreteEmployee> EndGetAllVacancies(IAsyncResult result)
            {
                var asyncResult = result as AsyncResult<List<ConcreteEmployee>>;
                if (null == asyncResult)
                    return null;
                
                try
                {
                    return asyncResult.Data;
                }
                finally
                {
                    asyncResult.Complete();
                }
            }
    
            #endregion
        }
    
    
    
    Clientside code:

      IEmployeeService client =
                    new ChannelFactory<IEmployeeService>("BasicHttpBinding_IEmployeeService").CreateChannel();
                AsyncCallback asyncCallback = delegate(IAsyncResult result)
                                                  {
                                                      try
                                                      {
                                                          List<ConcreteEmployee> employees =
                                                              ((IEmployeeService)result.AsyncState).EndGetAllVacancies(
                                                                  result);
                                                          }
                                                      }
                                                      catch (FaultException<FaultDetail>)
                                                      {
                                                          Debug.WriteLine(
                                                              "There was an error...(FaultException<FaultDetail)");
                                                      }
                                                      catch (FaultException)
                                                      {
                                                          Debug.WriteLine("There was an error...(FaultException)");
                                                      }
                                                      catch (Exception)
                                                      {
                                                          Debug.WriteLine("There was an error...(Exception)");
                                                      }
                                                  };
                client.BeginGetAllVacancies(asyncCallback, client);
    
    

    When I get my data on the server side everything is filled out correctly. When the data enters the SL client app, only the BaseEmployee types are filled, the other props are empty.

    I also tried the netdata serializer, without success.
    I also tried the 'add service reference' in Visual Studio, but without success.

    Does anybody has a clew what is going on?

Answers

  • Saturday, November 07, 2009 6:21 AMCarlos FigueiraMSFTUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Can you try decorating the properties of the derived classes with [DataMember] as well? [DataContract] classes will only serialize members which are marked as [DataMember].
    • Marked As Answer byKrikke999 Saturday, November 07, 2009 10:40 AM
    •  

All Replies

  • Saturday, November 07, 2009 6:21 AMCarlos FigueiraMSFTUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Can you try decorating the properties of the derived classes with [DataMember] as well? [DataContract] classes will only serialize members which are marked as [DataMember].
    • Marked As Answer byKrikke999 Saturday, November 07, 2009 10:40 AM
    •  
  • Saturday, November 07, 2009 10:40 AMKrikke999 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    After cleaning my WCF classes, so they didn't have the INotifyPropertyChanged and Redo/Undo patterns. I accidently deleted the [DataMember] attributes :-s

    That I didn't see that...

    Thanks for the experts eye :-)!