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 <dylancjan...@gmail.com>: > 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; > host.Description.Behaviors.Add( httpGetBehaviour ); > host.Open(); > RunningServiceHosts.Add(host); > } > catch (CommunicationException ce) > { > host.Abort(); > throw new Exception("Something Bad Happened", ce); > } > } > > public override void Destroy() > { > foreach (ServiceHost host in RunningServiceHosts) > { > host.Close(); > } > this.RunningServiceHosts.Clear(); > } > } > [/code] > > [b]The Windsor Impl[/b] > [code] > public class WindsorServiceHostCache : IServiceHostCache > { > public override void HostService(String ServiceName, String > ServiceType, Type ServiceContractImpl) > { > Uri uri = this.GenerateServiceUri(ServiceName, > ServiceType); > DefaultServiceHostFactory.RegisterContainer > (((IWindsorContainer) ObjectFactory.FetchDelegate()).Kernel); > DefaultServiceHost host = > new DefaultServiceHost(ServiceContractImpl, uri); > try > { > host.AddServiceEndpoint( > ServiceContractImpl, > new WSHttpBinding(), > ServiceName); > ServiceMetadataBehavior httpGetBehaviour = > new ServiceMetadataBehavior(); > httpGetBehaviour.HttpGetEnabled = true; > host.Description.Behaviors.Add(httpGetBehaviour); > host.Open(); > RunningServiceHosts.Add(host); > } > catch (CommunicationException ce) > { > host.Abort(); > throw new Exception("Something Bad Happened", ce); > } > this.RunningServiceHosts.Add(host); > } > > public override void Destroy() > { > foreach (DefaultServiceHost host in > this.RunningServiceHosts) > { > host.Close(); > } > this.RunningServiceHosts.Clear(); > } > } > [/code] > > [b]My Application Configuration[/b] > [code] > <?xml version="1.0" encoding="utf-8" ?> > <configuration> > <configSections> > <section name="castle" > > type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, > Castle.Windsor" /> > </configSections> > > <castle> > <facilities> > <!-- NHibernate Active Record Facility --> > <facility > id="arfacility" > > type="Castle.Facilities.ActiveRecordIntegration.ActiveRecordFacility, > Castle.Facilities.ActiveRecordIntegration" > isDebug="true" > isWeb="false"> > <assemblies> > <item>jTekPos.Data.Model</item> > </assemblies> > <config> > <add key="connection.driver_class" > value="NHibernate.Driver.MySqlDataDriver" /> > <add key="dialect" value="NHibernate.Dialect.MySQLDialect" /> > <add key="connection.provider" > value="NHibernate.Connection.DriverConnectionProvider" /> > <add key="connection.connection_string" > value="Database=jtekposclientdb;Data Source=localhost;User > Id=root;Password=mrozio" /> > <add key="proxyfactory.factory_class" > value="NHibernate.ByteCode.LinFu.ProxyFactoryFactory, > NHibernate.ByteCode.LinFu" /> > <add key="hbm2ddl.keywords" value="none" /> > </config> > </facility> > > <!-- ActiveRecord Automatic Transaction Management --> > <facility > id="atm" > > type="Castle.Facilities.AutomaticTransactionManagement.TransactionFacility, > Castle.Facilities.AutomaticTransactionManagement" /> > </facilities> > </castle> > </configuration> > [/code] > > And the remote client I use is basicly the selfgenerated code from > that svcutil.exe thing. > > Sorry for asking you guys for help - But I have been struggling with > this whole project setup the whole of today and yesterday. > > Please if I'm posting in the wrong place - just lemme know. > > [/code] > > -- > > You received this message because you are subscribed to the Google Groups > "Castle Project Users" group. > To post to this group, send email to castle-project-us...@googlegroups.com. > To unsubscribe from this group, send email to > castle-project-users+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/castle-project-users?hl=en. > > > -- You received this message because you are subscribed to the Google Groups "Castle Project Users" group. To post to this group, send email to castle-project-us...@googlegroups.com. To unsubscribe from this group, send email to castle-project-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/castle-project-users?hl=en.