WCF DataContract/inheritance
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4

Thread: WCF DataContract/inheritance

  1. #1
    Join Date
    Feb 2001
    Posts
    872

    WCF DataContract/inheritance

    Problem: trying to wire down the following class through WCF and run into deserialization problem:
    Code:
    	[KnownType("GetKnownType")]
    	[DataContract(Name = "Person", Namespace="xxxxx.Util")]
    	public class Person : IPerson, IGenericObjectOwner
    	{
    		#region KnownType attribute - Generic type, REF: http://msdn.microsoft.com/en-us/library/ms730167.aspx
    		private static Type[] GetKnownType()
    		{
    			Type[] t = new Type[3];
    			// t[0] = typeof(xxxxx.Util.Security.SystemUser);  // I purposedly comment this out for reasons below. 
    			t[0] = typeof(xxxxx.Util.Generic.GenericObject);
    			t[1] = typeof(xxxxx.Util.Security.BasicAudit);
    			t[2] = typeof(xxxxx.Util.Name);
    			return t;
    		}
    		...
                    [DataMember()]
           public IGenericObject GenericObj { get... set...}  // interface IGenericObjectOwner contains an IGenericObject (which contains parent/child Person)
    
    	}
    	
    	[DataContract(Name = "SystemUser", Namespace = "xxxxx.Util.Security")]
    	[GenericObjectAttribute(ObjectClassifier = "Person")]
    	public class SystemUser : Person, ISystemUser
    	{
    		...
    	}
    
    public interface IGenericObjectOwner
        {
            IGenericObject GenericObj
            {
                get;
                set;
            }
            ...
        }
    
       public class GenericObject : IGenericObject
       {
          ...
          [DataMember()]
           public virtual List<IGenericObjectOwner> Parents      // IGenericObject has "Parents" and "Children"
           {
                 // Commenting this out fixed the person proxy/serialization problem mentioned below
                /*
                get { return _lstParents; }
                set { _lstParents = value; }
                 */
    
                get { return new List<IGenericObjectOwner>(); }
                set { }
          }
    
          [DataMember()]
            public virtual List<IGenericObjectOwner> Children
            {
                 // Commenting this out fixed the person proxy/serialization problem mentioned below
                /*
                get { return _lstChildren; }
                set { _lstChildren = value; }
                 */
    
                get { return new List<IGenericObjectOwner>();  }
                set { }
            }
          ...
       }
    I checked Reference.cs,
    Code:
    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ISecurityService/GetPerson", ReplyAction="http://tempuri.org/ISecurityService/GetPersonResponse")]
            [System.ServiceModel.ServiceKnownTypeAttribute(typeof(xxxxx.Util.Security.SystemUser))] << QUESTION: Why is it not xxxxx.Util.Person?
            ...
            xxxxx.Util.Person GetPerson(string strEmail);
    And when I actually invoked the Service, I keep getting this error:
    Code:
    		
    		Type 'PersonProxy9ab9661107bd4ad9a11c877daa3d0e7d' with data contract name 'Person:xxxxx.Util' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
    I then proceed to modify Reference.cs manually to add xxxxx.Util.Person to known type (replace "xxxxx.Util.Security.SystemUser" above"), I still end up with the same error.

    My mind is not really functioning now after long struggles with this last few days but I stumbled on this:

    http://eddiedebear.blogspot.com/2008...heritance.html

    Not sure if it has to do with IExtensibleDataObject but I gave it a try and did NOT resolve the problem. Read further and figured out that IExtensibleDataObject only has to do with versioning (not what I'm facing right now, see this: http://codeidol.com/csharp/wcf/Data-...cts/Versioning)
    Thanks and hope someone can point me to right direction in this regards.
    Last edited by THY02K; March 17th, 2009 at 06:41 AM.

  2. #2
    Join Date
    Feb 2001
    Posts
    872

    Re: WCF DataContract/inheritance

    does it has to do with NHibernate? Person is loaded using NHibernate like this on server side:
    Code:
    Person oPerson = null;
    PersonDAO oPersonDAO = new PersonDAO();
    oPersonDAO.OpenSession();
    oCriteria = oPersonDAO.DBSession.CreateCriteria(typeof(Person));
    oCriteria.Add(Expression.Eq("PrimaryEmail", strEmail));
    lstResult = oPersonDAO.Find(oCriteria, Int32.MaxValue);
    if (lstResult.Count > 0)
    {
    oPerson = (Person) lstResult[0];
    return oPerson;
    }
    oPerson is a "xxxxx.Util.Security.SystemUser", it's also a "xxxxx.Util.Person" but certainly not a proxy (I checked it on NHibernate debugger). Also it doesn't look like it has to do with NHibernate lazy load even though problem arises from Person.GenericObject.Parents/Children collection because Parents/Children are not populated by NHibernate - it's done by code I wrote myself so no lazy loading issue here.

  3. #3
    Join Date
    Feb 2001
    Posts
    872

    Re: WCF DataContract/inheritance

    Sorry I just found out the children is indeed NHibernate proxies

    Code:
    [PersonProxya4d5a6ec378c4c049f205902f1912564]    {xxxxx.Util.Security.SystemUser, PersonId:0, Logon:guest, PasswdHash:159802048,ThinkFundamentals.Util.Person, Id:2, Name:xxxxx.Util.Name, FirstName:guest, MiddleName:, LastName:guest, PrimaryEmail:guest@xxxxx.com, Type:undefined, GenericObj:object type: xxxxx.Util.Generic.GenericObject, object name: , object classifier: Person, TypeName: ThinkFundamentals.Util.Person, DAOTypeName: xxxxx.Util.PersonDAO, Util, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null, DAOCreateInstanceArg: , CreateDate: 3/18/2009 10:40:19 AM, Properties: , Parents:, Children:, BasicAudit:ThinkFundamentals.Util.Security.BasicAudit, CreateDate:3/18/2009 10:37:48 AM, CreatedBy:1, LastUpdate:3/18/2009 10:37:48 AM, LastUpdateBy:1}    PersonProxya4d5a6ec378c4c049f205902f1912564
    __interceptors    {Castle.Core.Interceptor.IInterceptor[1]}    Castle.Core.Interceptor.IInterceptor[]
    Any suggestion? seems like I'd need to do a lot of Googling... but at least root cause found... further suggestion in dealing with NHibernate proxy/WCF be very good, anyone?! I can't add [DataContract] to NHibernate proxy...
    Last edited by THY02K; March 17th, 2009 at 09:50 PM.

  4. #4
    Join Date
    Feb 2001
    Posts
    872

    Found solution to WCF/NHibernate proxy problem!

    I found the answer!!!!!!!!!!

    Instead of calling NHibernate ISession.Load, I called ISession.Get - you'd get an instance of xxxxx.Util.Person instead of the NHibernate proxy.

    Hurrah!!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center