Web Services - Type Marshaling
-
There is a need for custom data types to be passed and returned in Web Services methods. As far as i know WS type marshaling is been handled by XmlSerializer which has some certain limitations. According to some of these limitations only the public fields properties and fields are serialized and any private and protected members will be ignored.This fact leeds to a certain problem because either infriges data encapsulation or break business objects' logic and rules (e.g. some properties of the business objects returned by the WS-method should have a "getter" only in order to serve the logic and i can make any compromise in this issue.) So... The questions are : 1.) Can i bypass this fact of ignoring private or protected members ? (Reflection does so...) 2.) If WS were not marshaling via a XmlSerializer whould the problem still existed due to some technical specs of WSs ? 3.) Let's suppose this is a limitation of XmlSerializer can i substitute it with another formatter to achieve my goal ? Thanx in advance, i would appreciate very much some help.
-
There is a need for custom data types to be passed and returned in Web Services methods. As far as i know WS type marshaling is been handled by XmlSerializer which has some certain limitations. According to some of these limitations only the public fields properties and fields are serialized and any private and protected members will be ignored.This fact leeds to a certain problem because either infriges data encapsulation or break business objects' logic and rules (e.g. some properties of the business objects returned by the WS-method should have a "getter" only in order to serve the logic and i can make any compromise in this issue.) So... The questions are : 1.) Can i bypass this fact of ignoring private or protected members ? (Reflection does so...) 2.) If WS were not marshaling via a XmlSerializer whould the problem still existed due to some technical specs of WSs ? 3.) Let's suppose this is a limitation of XmlSerializer can i substitute it with another formatter to achieve my goal ? Thanx in advance, i would appreciate very much some help.
Keep in mind that the client doesn't get the full type information of your object. It only gets an object containing your public fields. The web service is really just a collection of methods which pass simple data objects back and forth. Think C-structs rather then C++ objects. If you are returning the data from an existing object, you can markup your object with various XmlSerialization attributes to determine which properties and fields are serialized.
I can imagine the sinking feeling one would have after ordering my book, only to find a laughably ridiculous theory with demented logic once the book arrives - Mark McCutcheon
-
Keep in mind that the client doesn't get the full type information of your object. It only gets an object containing your public fields. The web service is really just a collection of methods which pass simple data objects back and forth. Think C-structs rather then C++ objects. If you are returning the data from an existing object, you can markup your object with various XmlSerialization attributes to determine which properties and fields are serialized.
I can imagine the sinking feeling one would have after ordering my book, only to find a laughably ridiculous theory with demented logic once the book arrives - Mark McCutcheon
You are right...A WS doesnt actually returns the object but a simple representation of it.I achieved to bypass the XmlSerialization in a way (not completely) by returning from my methods a byte array which actually is a memory stream of the object after being serialized via a binary formatter.This helped me achieve the consistency of my business objects and saved me from marking every single property from the XmlSerialition attribute. Thanx.
-
You are right...A WS doesnt actually returns the object but a simple representation of it.I achieved to bypass the XmlSerialization in a way (not completely) by returning from my methods a byte array which actually is a memory stream of the object after being serialized via a binary formatter.This helped me achieve the consistency of my business objects and saved me from marking every single property from the XmlSerialition attribute. Thanx.
-
I'm interested in why you serialised as binary and not XML - was it just a matter of personal choice ? I have similar issues to solve - did this approach work OK for collections as well ?
No its not a matter of personnal choice.I did it because of the following reasons. 1.) XmlSerialization serializes mainly primitive types and if not, every property,class or WS-method should be marked with XmlIncludeAttribute where needed (rather time consuming and very ugly code output). In addition XmlSerializer fails if there are circular dependencies in the non-primitive type. 2.) By returning a byte array i get rid of the ugly proxies generated in the web service stub.e.g if i returned from ws-method a BusinessObject (hypothetical class) i would end up in my client code with one real definition for BusinessObject in my business access layer code and one in the ws stub. Boring and messy. 3.) Because of XmlSerializer reflection issue (see my initial thread) i could not keep up with the consistency required by my business objects. 3.) Binary formatter serializes all objects as long as are marked with SerializableAttribute or if they implement ISerializable. 4.) I can compress the output directly when its created with minimal overhead (especially network overhead). 5.) I wanted a more generic approach of my middleware so future changes wouldn't affect clients. So because WS doesn't allow Generic methods in the shake of interoperability i considered using a byte array Yes it's ok for collections see point 3.) I hope i covered you.
-
No its not a matter of personnal choice.I did it because of the following reasons. 1.) XmlSerialization serializes mainly primitive types and if not, every property,class or WS-method should be marked with XmlIncludeAttribute where needed (rather time consuming and very ugly code output). In addition XmlSerializer fails if there are circular dependencies in the non-primitive type. 2.) By returning a byte array i get rid of the ugly proxies generated in the web service stub.e.g if i returned from ws-method a BusinessObject (hypothetical class) i would end up in my client code with one real definition for BusinessObject in my business access layer code and one in the ws stub. Boring and messy. 3.) Because of XmlSerializer reflection issue (see my initial thread) i could not keep up with the consistency required by my business objects. 3.) Binary formatter serializes all objects as long as are marked with SerializableAttribute or if they implement ISerializable. 4.) I can compress the output directly when its created with minimal overhead (especially network overhead). 5.) I wanted a more generic approach of my middleware so future changes wouldn't affect clients. So because WS doesn't allow Generic methods in the shake of interoperability i considered using a byte array Yes it's ok for collections see point 3.) I hope i covered you.
Great feedback - thanks. My motives for querying this are really based on point (2) - I don't want unneccessary business entity proxies being duplicated in the WS consumer/client; I actually have a leaning towards binary serilisation and its great to hear that it addresses all concerns.