Home
Help
Register
Log in

Search

 
   Active Threads  

You are here: Home > LLBLGen Pro > Bugs & Issues> UnitOfWork2 WCF Serialization
 

Pages: 1
Bugs & Issues
UnitOfWork2 WCF Serialization
Page:1/1 

  Print all messages in this thread  
Poster Message
saggett
User



Location:
Manchester, UK
Joined on:
12-Nov-2007 15:44:46
Posted:
50 posts
# Posted on: 12-Nov-2007 17:22:55.  
When using UnitOfWork2 as a parameter of a method on a WCF Service (having added it as a known type by attributing the Service Contract), I receive the following error:

System.ServiceModel.CommunicationException occurred
Message="There was an error while trying to serialize parameter http://tempuri.org/:unitOfWork. The InnerException message was 'Type 'System.Collections.Generic.List`1[[SD.LLBLGen.Pro.ORMSupportClasses.UnitOfWorkCallBackElement2, SD.LLBLGen.Pro.ORMSupportClasses.NET20, Version=2.5.0.0, Culture=neutral, PublicKeyToken=ca73b74ba4e3ff27]]' with data contract name 'ArrayOfUnitOfWorkCallBackElement2:http://schemas.datacontract.org/2004/07/SD.LLBLGen.Pro.ORMSupportClasses' 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.'. Please see InnerException for more details."
Source="mscorlib"
StackTrace:
    Server stack trace:
     at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameterPart(XmlDictionaryWriter writer, PartInfo part, Object graph)
     at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameter(XmlDictionaryWriter writer, PartInfo part, Object graph)
     at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameters(XmlDictionaryWriter writer, PartInfo[] parts, Object[] parameters)
     at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeBody(XmlDictionaryWriter writer, MessageVersion version, String action, MessageDescription messageDescription, Object returnValue, Object[] parameters, Boolean isRequest)
     at System.ServiceModel.Dispatcher.OperationFormatter.SerializeBodyContents(XmlDictionaryWriter writer, MessageVersion version, Object[] parameters, Object returnValue, Boolean isRequest)
     at System.ServiceModel.Dispatcher.OperationFormatter.OperationFormatterMessage. OperationFormatterBodyWriter.OnWriteBodyContents(XmlDictionaryWriter writer)
     at System.ServiceModel.Channels.BodyWriter.WriteBodyContents(XmlDictionaryWriter writer)
     at System.ServiceModel.Channels.BodyWriterMessage.OnWriteBodyContents(XmlDictionaryWriter writer)
     at System.ServiceModel.Channels.Message.WriteBodyContents(XmlDictionaryWriter writer)
     at System.ServiceModel.Security.SecurityAppliedMessage.WriteBodyToSignThenEncryptWithFragments(Stream stream, Boolean includeComments, String[] inclusivePrefixes, EncryptedData encryptedData, SymmetricAlgorithm algorithm, XmlDictionaryWriter writer)
     at System.ServiceModel.Security.WSSecurityOneDotZeroSendSecurityHeader.ApplyBodySecurity(XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator)
     at System.ServiceModel.Security.SecurityAppliedMessage.OnWriteMessage(XmlDictionaryWriter writer)
     at System.ServiceModel.Channels.Message.WriteMessage(XmlDictionaryWriter writer)
     at System.ServiceModel.Channels.BufferedMessageWriter.WriteMessage(Message message, BufferManager bufferManager, Int32 initialOffset, Int32 maxSizeQuota)
     at System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager, Int32 messageOffset)
     at System.ServiceModel.Channels.MessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager)
     at System.ServiceModel.Channels.HttpOutput.SerializeBufferedMessage(Message message)
     at System.ServiceModel.Channels.HttpOutput.Send(TimeSpan timeout)
     at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.SendRequest(Message message, TimeSpan timeout)
     at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
     at System.ServiceModel.Channels.ClientReliableChannelBinder`1.RequestClientReliableChannelBinder`1. OnRequest(TRequestChannel channel, Message message, TimeSpan timeout, MaskingMode maskingMode)
     at System.ServiceModel.Channels.ClientReliableChannelBinder`1.Request(Message message, TimeSpan timeout, MaskingMode maskingMode)
     at System.ServiceModel.Channels.ClientReliableChannelBinder`1.Request(Message message, TimeSpan timeout)
     at System.ServiceModel.Security.SecuritySessionClientSettings`1.SecurityRequestSessionChannel.Request(Message message, TimeSpan timeout)
     at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
     at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
     at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
     at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
     at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
    Exception rethrown at [0]:
     at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
     at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
     at UnivarQ.ServiceContracts.IUnivarQWork.CommitEntityUnitOfWork(UnitOfWork2 unitOfWork, EntityType rootEntityType)
     at UnivarQ.ClientUILib.ServiceProxy.ClientUnivarQWork.CommitUnitOfWork(UnitOfWork2 unitOfWork, EntityType rootEntityType) in C:\Projects\LatestU\UI\ClientUILib\ServiceProxy\ClientUnivarQWork.cs:line 115


The Service Contract Interface already includes the following attributes:

    [ServiceKnownType(typeof(UnitOfWorkElement2))]
    [ServiceKnownType(typeof(UnitOfWorkCollectionElement2))]
    [ServiceKnownType(typeof(List<UnitOfWorkElement2>))]
    [ServiceKnownType(typeof(List<UnitOfWorkCollectionElement2>))]
    [ServiceKnownType(typeof(Dictionary<System.Guid, UnitOfWorkElement2>))]
    [ServiceKnownType(typeof(Dictionary<System.Guid, UnitOfWorkCollectionElement2>))]

which were all required for the DataContractSerializer to serialize a UnitOfWork2 object. However, when attempting to add the attribute:
[ServiceKnownType(typeof(List<SD.LLBLGen.Pro.ORMSupportClasses.UnitOfWorkCallBackElement2>))]

I receive the compiler error 'SD.LLBLGen.Pro.ORMSupportClasses.UnitOfWorkCallBackElement2' is inaccessible due to its protection level'.

Is there any resolution for my problem, other than not using UnitOfWork2 as a parameter in a WCF service? I assumed that the UnitOfWork2 class would be serializable by the DataContractSerializer, given that the documentation states that the class is xml serializable.

  Top
goose
User



Location:
Central America
Joined on:
06-Aug-2007 18:21:05
Posted:
385 posts
# Posted on: 12-Nov-2007 18:01:59.  
Hi, this thread contains a similar question, let me know if you need further help.

http://llblgen.com/TinyForum/Messages.aspx?ThreadID=11493



gansodesoya  Top
saggett
User



Location:
Manchester, UK
Joined on:
12-Nov-2007 15:44:46
Posted:
50 posts
# Posted on: 12-Nov-2007 18:05:01.  
I read that thread, but there didn't seem to be a fix for the problem. Should I take it then that the UnitOfWork2 cannot be serialized, contrary to what it says in the documentation, and that there are no plans to change this?
  Top
Otis
LLBLGen Pro Team



Location:
The Hague, The Netherlands
Joined on:
17-Aug-2003 18:00:36
Posted:
37373 posts
# Posted on: 12-Nov-2007 18:27:17.  
Serialization isn't always the same: UnitOfWork2 is serializable over remoting, but not over XML. WCF uses XML if you're not using remoting over WCF. So if you want to send UnitOfWork2 objects, you either have to use remoting, or use messages instead of sending a unitofwork2.

We're thinking about making UnitOfWork2 objects XML serializable (that's something else than remoting serializable Wink) in a future version, as it shouldn't be that much work (the beef is already done as entitycollections and entities are already serializable over XML)


Frans Bouma
LLBLGen Pro / ORM Profiler Lead Developer | Blog | Twitter
 
Top
saggett
User



Location:
Manchester, UK
Joined on:
12-Nov-2007 15:44:46
Posted:
50 posts
# Posted on: 13-Nov-2007 11:30:35.  
Would utilizing NetDataContractSerializer rather than DataContractSerializer do the trick, given that NetDataContractSerializer seems to be Microsoft's WCF version of Remoting?
  Top
Otis
LLBLGen Pro Team



Location:
The Hague, The Netherlands
Joined on:
17-Aug-2003 18:00:36
Posted:
37373 posts
# Posted on: 13-Nov-2007 18:28:55.  
saggett wrote:
Would utilizing NetDataContractSerializer rather than DataContractSerializer do the trick, given that NetDataContractSerializer seems to be Microsoft's WCF version of Remoting?

I don't think that will give remoting, as it still serializes to XML. Remoting under WCF is IMHO not really 'there', WCF is pure XML, remoting over WCF therefore isn't possible, you simply have to use remoting using the normal proven way to setup remoting. The WCF + remoting docs suggest either migration to WCF (Which imho implies XML) or side-by-side.


Frans Bouma
LLBLGen Pro / ORM Profiler Lead Developer | Blog | Twitter
 
Top
mihies
User



Location:
Nova Gorica, Slovenia
Joined on:
29-Jan-2006 16:00:15
Posted:
797 posts
# Posted on: 21-Dec-2008 18:22:17.  
Otis wrote:
Serialization isn't always the same: UnitOfWork2 is serializable over remoting, but not over XML. WCF uses XML if you're not using remoting over WCF. So if you want to send UnitOfWork2 objects, you either have to use remoting, or use messages instead of sending a unitofwork2.

We're thinking about making UnitOfWork2 objects XML serializable (that's something else than remoting serializable Wink) in a future version, as it shouldn't be that much work (the beef is already done as entitycollections and entities are already serializable over XML)


Was it ever implemented?
Miha Markic
MVP C#, LLBLGenPro Partner, DXSquad
Blog, Twitter
 
Top
Otis
LLBLGen Pro Team



Location:
The Hague, The Netherlands
Joined on:
17-Aug-2003 18:00:36
Posted:
37373 posts
# Posted on: 21-Dec-2008 18:57:35.  
No unfortunately not, as we ran into a problem with deserializing predicates and relationships in update with filter saves: it is required to deserialize fields in that case, however the UoW has no access to any factory when doing so.

We'll implemented in v3 even if it requires changes to the system. Also planned is a way to diff the elements to serialize so the data is really compact.


Frans Bouma
LLBLGen Pro / ORM Profiler Lead Developer | Blog | Twitter
 
Top
mihies
User



Location:
Nova Gorica, Slovenia
Joined on:
29-Jan-2006 16:00:15
Posted:
797 posts
# Posted on: 21-Dec-2008 19:49:43.  
Otis wrote:
No unfortunately not, as we ran into a problem with deserializing predicates and relationships in update with filter saves: it is required to deserialize fields in that case, however the UoW has no access to any factory when doing so.

We'll implemented in v3 even if it requires changes to the system. Also planned is a way to diff the elements to serialize so the data is really compact.


Interesting. Right now I am thinking about how to efficiently transfer graphs forth and back (main transport is WCF).
One way would be to use DTO. When fetching I'd create (fetch from database) entity graph on server side, project it to DTO graph (it shouldn't be difficult) that'd travel over the wire. The DTO graphs should be used to recreate entity graph on client side.

When saving, I'd collect all dirty entities from that graph and create DTO objects from them (perhaps by using UoW - I'd have the right order of operation). I'd send DTO over the wire, on server create all entities in correct order and save them in a transaction.

But if you are going to make the save step "out of the box" then the DTOs aren't really required anymore since the fetch scenario doesn't really require them.
Miha Markic
MVP C#, LLBLGenPro Partner, DXSquad
Blog, Twitter
 
Top
Otis
LLBLGen Pro Team



Location:
The Hague, The Netherlands
Joined on:
17-Aug-2003 18:00:36
Posted:
37373 posts
# Posted on: 23-Dec-2008 11:19:09.  
mihies wrote:
Otis wrote:
No unfortunately not, as we ran into a problem with deserializing predicates and relationships in update with filter saves: it is required to deserialize fields in that case, however the UoW has no access to any factory when doing so.

We'll implemented in v3 even if it requires changes to the system. Also planned is a way to diff the elements to serialize so the data is really compact.


Interesting. Right now I am thinking about how to efficiently transfer graphs forth and back (main transport is WCF).
One way would be to use DTO. When fetching I'd create (fetch from database) entity graph on server side, project it to DTO graph (it shouldn't be difficult) that'd travel over the wire. The DTO graphs should be used to recreate entity graph on client side.

When saving, I'd collect all dirty entities from that graph and create DTO objects from them (perhaps by using UoW - I'd have the right order of operation). I'd send DTO over the wire, on server create all entities in correct order and save them in a transaction.

But if you are going to make the save step "out of the box" then the DTOs aren't really required anymore since the fetch scenario doesn't really require them.

Actually, one only needs to send the EntityFields2 objects, and then only the values which are changed (or set to a value), and graph information, and it should be possible to re-build the graph on the other side, though this does require logic which isn't there yet. Regular Smiley.

You have to collect all dirty entities + all entities which receive an FK value from a PK side. for example employee E will now work for a new department D. E isn't 'dirty' though after D is saved, E's WorksForDepartmentId will be changed (with the new id for D) and E will be dirty. This is done for you by the action queue producer methods in ObjectGraphUtils. The entities produced by these routines are the ones to sent. At the moment, the reference hierarchies aren't cut off properly for serialization. So if these queues are serialized, the entities they reference are still serialized too, while that shouldn't be done.


Frans Bouma
LLBLGen Pro / ORM Profiler Lead Developer | Blog | Twitter
 
Top
mihies
User



Location:
Nova Gorica, Slovenia
Joined on:
29-Jan-2006 16:00:15
Posted:
797 posts
# Posted on: 23-Dec-2008 11:47:41.  
Quote:
Actually, one only needs to send the EntityFields2 objects, and then only the values which are changed (or set to a value), and graph information, and it should be possible to re-build the graph on the other side, though this does require logic which isn't there yet. Regular Smiley.


Yep, that's all its needed.

Quote:
You have to collect all dirty entities + all entities which receive an FK value from a PK side. for example employee E will now work for a new department D. E isn't 'dirty' though after D is saved, E's WorksForDepartmentId will be changed (with the new id for D) and E will be dirty. This is done for you by the action queue producer methods in ObjectGraphUtils. The entities produced by these routines are the ones to sent. At the moment, the reference hierarchies aren't cut off properly for serialization. So if these queues are serialized, the entities they reference are still serialized too, while that shouldn't be done.


That's actually one of the two problems. Currently I am using some sort of remoting and UoW thus too much data is sent unnecessarily.
So, if you create a WCF serializable UoW and a good pruning algorithm that would be just awesome. Regular Smiley
Miha Markic
MVP C#, LLBLGenPro Partner, DXSquad
Blog, Twitter
 
Top
Otis
LLBLGen Pro Team



Location:
The Hague, The Netherlands
Joined on:
17-Aug-2003 18:00:36
Posted:
37373 posts
# Posted on: 28-Dec-2008 11:46:54.  
mihies wrote:

Quote:
You have to collect all dirty entities + all entities which receive an FK value from a PK side. for example employee E will now work for a new department D. E isn't 'dirty' though after D is saved, E's WorksForDepartmentId will be changed (with the new id for D) and E will be dirty. This is done for you by the action queue producer methods in ObjectGraphUtils. The entities produced by these routines are the ones to sent. At the moment, the reference hierarchies aren't cut off properly for serialization. So if these queues are serialized, the entities they reference are still serialized too, while that shouldn't be done.


That's actually one of the two problems. Currently I am using some sort of remoting and UoW thus too much data is sent unnecessarily.
So, if you create a WCF serializable UoW and a good pruning algorithm that would be just awesome. Regular Smiley

Regular Smiley Let's see how far I can get with v3's attempt at this problem. Regular Smiley


Frans Bouma
LLBLGen Pro / ORM Profiler Lead Developer | Blog | Twitter
 
Top
mihies
User



Location:
Nova Gorica, Slovenia
Joined on:
29-Jan-2006 16:00:15
Posted:
797 posts
# Posted on: 28-Dec-2008 11:58:44.  
Otis wrote:

Regular Smiley Let's see how far I can get with v3's attempt at this problem. Regular Smiley


I don't doubt it will be just perfect. Regular Smiley And then the n-tier capability will be unleashed!
Miha Markic
MVP C#, LLBLGenPro Partner, DXSquad
Blog, Twitter
 
Top
Pages: 1  


Powered by HnD ©2002-2007 Solutions Design
HnD uses LLBLGen Pro

Version: 2.1.12172008 Final.