WCF and NHibernate
Hi,
I use a wcf with a nhibernate, but when I call a service occur an error. Only occur when nhibernate return a collection of objects (Person) with their children:
[Datacontract]
public Person
{
private List<Person> children;
[Datamember]
public List<Person> Children
{
...
Somebody can help me?
Thank you!!
[401 byte] By [
shido] at [2007-12-24]
That is your problem. You can't expose non serializable types as part of a service contract. You have two options to work around this:
- Create a data contract that looks like the types you want and expose those in the service contract. As messages come in, you can map the facade type to the nhibernate type before processing at your business tier. As messages are returned you can control mapping the nhibernate type to the new data contract type before returning to clients. The clients sees the same type essentially. Pros: you can let the service model handle serialization for you. Cons: the service model deserializes the stream to a type that you subsequently will throw away once you map to nhibernate...so that creates overhead.
- An alternative, better performing, is IXmlSerializable types. This way, the service model gives you a chance to handle the XML read and write process for your nhibernate types. Create a wrapper type like "PersonSerializer" that implements IXmlSerializable, then override read/write to handle XML stream directly. Pros: less overhead and direct control over schema generation. Cons: you have to work with XML directly.
For a sample on #2 read my chapter 2 on www.thatindigogirl.com. I have extensive discussion on serialization in there, and an IXmlSerializable example.
we currently use like that, and we have good result, i was test 250 concurrent user over 15 different machine with a ThreadUser test. it work good.
public
ServiceResponse LoadORMQuerywPaging(object ORMQuery, int pagenumber, int pagesize, ref Entity[] modellistwPaging){
ServiceResponse response = new ServiceResponse();if (isvalidSession){
SoftLogger.writeInfo(String.Format(ResourceProvider.getRourceString(GetType(), "LoadObjectCRUDInfo"), ORMQuery.ToString(), "Entity"));IList listofType = new ArrayList();using (IPersistManager ipm = new NHibernateManager()){
listofType = ipm
.LoadByORMQuerywPage(ORMQuery, pagenumber, pagesize);
}
if (listofType.Count > 0){
modellistwPaging =
new Entity[listofType.Count];listofType.CopyTo(modellistwPaging, 0);
response.ResponseStatus =
ResponseStatus.Success;response.ResponseMessage =
String.Format(ResourceProvider.getRourceString(GetType(), "recordCountResponse"), listofType.Count);}
else{
modellistwPaging =
null;response.ResponseStatus =
ResponseStatus.Success;response.ResponseMessage =
String.Format(ResourceProvider.getRourceString(GetType(), "recordCountResponse"), listofType.Count);}
}
else{
response.ResponseStatus =
ResponseStatus.Fail;response.ResponseMessage =
String.Format(ResourceProvider.getRourceString(GetType(), "NotValidRegisterResponse"));}
return response;}