Thanks Richard!

The problem wasn't the serializer but writing the unit test made me
realise what the problem was : It was this part in StandardDAO.cs :
      public ICriteria MakeCriteria()
        {
            return _Session.CreateCriteria(typeof(T).Name);
        }
It wasn't actually trying to reference the actually entity and instead
it looked like a string value or something like that.
I still need to finish reading up on reflection...
But other than that u can have the entities extends from
ActiveRecordBase even when sending them over the wire!
Hope this helps someone else!

On Jan 3, 10:38 am, "G. Richard Bellamy" <[email protected]>
wrote:
> Perhaps build a test to see if you can serialize your model using the  
> XML serializer? That may provide a more meaningful exception, if that  
> is your problem.
>
> Sent from my mobile device. Please excuse any errors or omissions.
>
> On Jan 3, 2010, at 9:54 AM, dylanj <[email protected]> wrote:
>
> > Hi Markus, I stopped inheriting from ActiveRecordBase, and rebuild
> > everything I still get the same error.
>
> > On Jan 3, 9:01 am, Markus Zywitza <[email protected]> wrote:
> >> When you send your entities over the wire, you better don't inherit
> >> from ActiveRecordBase.
> >> Perhaps this solves your problem.
>
> >> -Markus
>
> >> 2010/1/3 dylanj <[email protected]>:
>
> >>> Hi All,
>
> >>> Sorry if this is a n00b thing to ask - I've only been into DotNet/C#
> >>> for about two weeks.
>
> >>> But basicly what I am trying to do is expose DAO's throught WCF
> >>> services.
>
> >>> The problem is when I try to call the Service from the client I get
> >>> the following exception : Test method
> >>> jTekPos.Client.RemoteProxy.Tests.UserProxy_Fixture.Can_We_Lookup_A_Member
> >>> threw exception:  System.ServiceModel.FaultException`1
> >>> [System.ServiceModel.ExceptionDetail]: No persister for: User.
>
> >>> I believe ( from what I have googled ) that it has something to do
> >>> with the Serializer not serializing the references properly, But I
> >>> have spent way to long googling and really need some help now.
>
> >>> My User.cs is defined here :
>
> >>> [code]
> >>> namespace jTekPos.Data.Model
> >>> {
> >>>    [Serializable]
> >>>    [DataContract]
> >>>    [ActiveRecord("usrs")]
> >>>    public class User : ActiveRecordBase<User>
> >>>    {
> >>>        [DataMember]
> >>>        [PrimaryKey("user_id")]
> >>>        public int UserId { get; set; }
>
> >>>        [DataMember]
> >>>        [Property("user_name")]
> >>>        public String Username { get; set; }
>
> >>>        [DataMember]
> >>>        [Property("pass_word")]
> >>>        public String Password { get; set; }
>
> >>>        [DataMember]
> >>>        [Property("firstname")]
> >>>        public String Firstname { get; set; }
>
> >>>        [DataMember]
> >>>        [Property("surname")]
> >>>        public String Surname { get; set; }
>
> >>>        [DataMember]
> >>>        [HasAndBelongsToMany(typeof(Role),
> >>>            Table = "usr_role_link", ColumnKey = "user_id", ColumnRef
> >>> = "role_id",
> >>>            Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Lazy =
> >>> true)]
> >>>        public IList<Role> Roles { get; set; }
> >>>    }
> >>> }
> >>> [/code]
>
> >>> My Role.cs is defined here :
> >>> [code]
> >>> namespace jTekPos.Data.Model
> >>> {
> >>>    [Serializable]
> >>>    [DataContract]
> >>>    [ActiveRecord("user_role")]
> >>>    public class Role : ActiveRecordBase<Role>
> >>>    {
> >>>        [DataMember]
> >>>        [PrimaryKey("role_id")]
> >>>        public int RoleId { get; set; }
>
> >>>        [DataMember]
> >>>        [Property("role_name")]
> >>>        public String RoleName { get; set; }
>
> >>>        [DataMember]
> >>>        [Property("role_desc")]
> >>>        public String RoleDescription { get; set; }
>
> >>>        [DataMember]
> >>>        [HasAndBelongsToMany(typeof(User),
> >>>            Table = "user_role_link", ColumnKey = "role_id",  
> >>> ColumnRef
> >>> = "user_id",
> >>>            Inverse = true, Cascade =
> >>> ManyRelationCascadeEnum.SaveUpdate, Lazy = true)]
> >>>        public IList<User> Users { get; set; }
>
> >>>        [DataMember]
> >>>        [HasAndBelongsToMany(typeof(Permission),
> >>>            Table = "role_perm_link", ColumnKey = "role_id",  
> >>> ColumnRef
> >>> = "perm_id",
> >>>            Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Lazy =
> >>> true)]
> >>>        public IList<Permission> Permissions { get; set; }
> >>>    }
> >>> }
> >>> [/code]
>
> >>> The DAO that I expose (UserDAO.cs) :
> >>> [code]
> >>> namespace jTekPos.Data.AccessObject
> >>> {
> >>>    [ServiceContract(Namespace="www.#####co.za/jTekPos/
> >>> DataAccessObject/User")]
> >>>    [ServiceBehavior(IncludeExceptionDetailInFaults=true,
> >>> MaxItemsInObjectGraph=1000)]
> >>>    public class UserDao : StandardDao<User>
> >>>    {
> >>>        [OperationContract]
> >>>        [PreserveCircularReferences]
> >>>        public virtual User FindUserById( int id )
> >>>        {
> >>>            return GetSingleResultFromCriteria
> >>> (MakeOneParamSimpleEqCriteria("Id", id));
> >>>        }
>
> >>>        [OperationContract]
> >>>        [PreserveCircularReferences]
> >>>        public virtual User FindUserByUsername(String username)
> >>>        {
> >>>            return GetSingleResultFromCriteria
> >>> (MakeOneParamSimpleEqCriteria("Username", username));
> >>>        }
> >>>    }
> >>> }
> >>> [/code]
>
> >>> The UserDao extends StandardDAO.cs thats this :
> >>> [code]
>
> >>> namespace jTekPos.Data.AccessObject
> >>> {
> >>>    public abstract class StandardDao<T>
> >>>    {
> >>>        public readonly ISession _Session;
> >>>        public T _BaseEntity;
>
> >>>        public StandardDao()
> >>>        {
> >>>            ISessionFactory factory =
> >>>                ObjectFactory.GetInstance<ISessionFactory>();
> >>>            _Session = factory.OpenSession();
> >>>            _BaseEntity = (T)
> >>>                typeof(T).GetConstructor(new Type[]{}).Invoke(new
> >>> Object[]{});
> >>>        }
>
> >>>        public ICriteria MakeCriteria()
> >>>        {
> >>>            return _Session.CreateCriteria(typeof(T).Name);
> >>>        }
>
> >>>        public ICriteria MakeOneParamSimpleEqCriteria(String
> >>> PropertyName, Object Value)
> >>>        {
> >>>            ICriteria crit = MakeCriteria();
> >>>            crit.Add(Restrictions.Eq(PropertyName, Value));
> >>>            return crit;
> >>>        }
>
> >>>        public T GetSingleResultFromCriteria(ICriteria iCrit)
> >>>        {
> >>>            iCrit.SetMaxResults(1);
> >>>            IList<T> lst = iCrit.List<T>();
> >>>            if (lst == null || lst.Count == 0)
> >>>                return default(T);
> >>>            return lst[0];
> >>>        }
> >>>    }
> >>> }
>
> >>> [/code]
>
> >>> I followed an Microsoft article recommending me to create these
> >>> (supposed to help the dataContractSerializer preserver my
> >>> references) :
>
> >>> [b]OpBehaviourPreserveRefs.cs[/b]
> >>> [code]
> >>> public class OpBehaviourPreserveRefs :
> >>> DataContractSerializerOperationBehavior
> >>>    {
> >>>         public OpBehaviourPreserveRefs ( OperationDescription
> >>> operationDescription) : base(operationDescription) { }
>
> >>>         public override XmlObjectSerializer CreateSerializer( Type
> >>> type, string name, string ns, IList<Type> knownTypes)
> >>>         {
> >>>            return CreateDataContractSerializer(type, name, ns,
> >>> knownTypes);
> >>>         }
>
> >>>         private static XmlObjectSerializer
> >>> CreateDataContractSerializer( Type type, string name, string ns,
> >>> IList<Type> knownTypes)
> >>>         {
> >>>            return CreateDataContractSerializer(type, name, ns,
> >>> knownTypes);
> >>>         }
>
> >>>         public override XmlObjectSerializer CreateSerializer( Type
> >>> type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type>
> >>> knownTypes)
> >>>         {
> >>>             return new DataContractSerializer(type, name, ns,
> >>> knownTypes, 0x7FFF, false, true, null);
> >>>         }
> >>>    }
> >>> [/code]
>
> >>> [b]The attribute : [/b]
> >>> [code]
> >>>  public class PreserveCircularReferencesAttribute : Attribute,
> >>> IOperationBehavior
> >>>    {
> >>>        public void AddBindingParameters(OperationDescription
> >>> description, BindingParameterCollection parameters) { }
>
> >>>        public void ApplyClientBehavior(OperationDescription
> >>> description, ClientOperation proxy) {
> >>>            IOperationBehavior innerBehavior =
> >>>              new OpBehaviourPreserveRefs(description);
> >>>            innerBehavior.ApplyClientBehavior(description, proxy);
> >>>        }
>
> >>>        public void ApplyDispatchBehavior(OperationDescription
> >>> description, DispatchOperation dispatch)
> >>>        {
> >>>            IOperationBehavior innerBehavior =
> >>>              new OpBehaviourPreserveRefs(description);
> >>>            innerBehavior.ApplyDispatchBehavior(description,
> >>> dispatch);
> >>>        }
>
> >>>        public void Validate(OperationDescription description) { }
> >>>    }
> >>> [/code]
>
> >>> And Then to host these I tried the standard selfHost option, and  
> >>> tried
> >>> the WcfIntegration package from Castle :
>
> >>> [b]IServiceHostCache.cs[/b]
> >>> [code]
> >>>  public abstract class IServiceHostCache
> >>>    {
> >>>        public const String URI_TEMPLATE =
> >>>            "http://${BindAddress}:${Port}/jtek/wcf/${ServiceType}/$
> >>> {ServiceName}";
>
> >>>        public IList<Object> RunningServiceHosts =
> >>>            new List<Object>();
>
> >>>        public abstract void HostService(String ServiceName, String
> >>> ServiceType, Type ServiceContractImpl);
>
> >>>        public Uri GenerateServiceUri(string ServiceName, string
> >>> ServiceType)
> >>>        {
> >>>            return new Uri(URI_TEMPLATE
> >>>                .Replace("${BindAddress}", "localhost")
> >>>                .Replace("${Port}", "8000")
> >>>                .Replace("${ServiceType}", ServiceType)
> >>>                .Replace("${ServiceName}", ServiceName));
> >>>        }
>
> >>>        public abstract void Destroy();
> >>> [/code]
>
> >>> [b]Standard WCF impl:[/b]
> >>> [code]
> >>>  public class WcfBasedServiceHostCache : IServiceHostCache
> >>>    {
> >>>        public override void HostService(String ServiceName, String
> >>> ServiceType, Type ServiceContractImpl)
> >>>        {
> >>>            Uri uri = GenerateServiceUri( ServiceName, ServiceType );
> >>>            ServiceHost host =
> >>>                new ServiceHost( ServiceContractImpl , uri );
> >>>            try
> >>>            {
> >>>                host.AddServiceEndpoint(
> >>>                    ServiceContractImpl,
> >>>                    new WSHttpBinding(),
> >>>                    ServiceName);
> >>>                ServiceMetadataBehavior httpGetBehaviour =
> >>>                    new ServiceMetadataBehavior();
> >>>                httpGetBehaviour.HttpGetEnabled = true;
>
> ...
>
> read more »

--

You received this message because you are subscribed to the Google Groups 
"Castle Project Users" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/castle-project-users?hl=en.


Reply via email to