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.