There are situations in which serialization is
required for persisting state of objects from WCF services. Starting
with .NET Framework 3.0, you can serialize objects exposed by WCF
services taking advantage of the DataContractSerializer class (which inherits from XmlObjectSerializer).
The usage of such a class is not so different from other serialization
classes. The only need is that you must mark your serializable classes
either with the Serializable or with the DataContract attribute and, in this case, their members with the DataMember attribute. To see how this works in code, create a new WCF service project within Visual Studio 2010 and name it WcfPersonService. Rename the default IService1 interface to IPersonService; then rename the default Service1 class to PersonService. The new service exposes a special implementation of the Person class. Listing 1 shows the complete code for the WCF sample service.
Listing 1. Exposing Serializable Objects from WCF Services
<ServiceContract()> Public Interface IPersonService
<OperationContract()> Function GetPersonFullName(ByVal onePerson As Person) As String End Interface
<DataContract()> Public Class Person
<DataMember()> Public Property FirstName As String
<DataMember()> Public Property LastName As String End Class Public Class PersonService Implements IPersonService
Public Function GetPersonFullName(ByVal onePerson As Person) As String _ Implements IPersonService.GetPersonFullName
Dim fullName As New Text.StringBuilder fullName.Append(onePerson.FirstName) fullName.Append(" ") fullName.Append(onePerson.LastName) Return fullName.ToString End Function End Class
|
Notice how you simply decorate the Person class and its members respectively with the DataContract and DataMember attributes. Now create a new console project for testing the WCF service and serialization. Name the new project as TestWcfSerialization; then add a service reference to the WcfPersonService project. This adds a reference to the WCF service creating a proxy
class in Visual Basic. All you need to do now is to get the instance of
the service client and invoke the DataContractSerializer class that requires a stream for putting serialized data to. Code in Listing 2 shows both serialization and deserialization processes.
Listing 2. Performing WCF Serialization
Imports TestWcfSerialization.PersonServiceReference Imports System.IO Imports System.Runtime.Serialization
Module Module1
Sub Main()
Dim client As New PersonServiceClient Dim p As New Person With {.FirstName = "Alessandro", .LastName = "Del Sole"}
Dim target As New FileStream("C:\Temp\WcfSerialized.xml", FileMode.Create) Dim serializer As New DataContractSerializer(GetType(Person)) serializer.WriteObject(target, p) target.Close() serializer = Nothing
Console.ReadLine() Dim source As New FileStream("C:\Temp\WcfSerialized.xml", FileMode.Open) serializer = New DataContractSerializer(GetType(Person))
Dim result As Person = CType(serializer.ReadObject(source), Person)
Console.WriteLine(result.LastName) Console.ReadLine() End Sub End Module
|
Notice how you invoke the WriteObject instance method for persisting data. The method requires the file stream instance and the data instance as arguments. WriteObject
can also serialize an entire object graph, similarly to the binary
standard serialization. Also notice that data is serialized to Xml
format. To deserialize objects you simply invoke the ReadObject instance method converting the result into the appropriate type. Serialization in WCF can cause special exceptions: InvalidDataContractException, which is thrown when the data contract on the service side is badly implemented, and System.ServiceModel.QuotaExceededException
that is thrown when serialization attempts to write a number of objects
greater than the allowed number. Such a number is represented by the DataContractSerializer.MaxItemsInObjectsGraph property and the default value is Integer.MaxValue. The following snippet shows how you catch the previously mentioned exceptions:
Try
serializer.WriteObject(target, p)
Catch ex As InvalidDataContractException
'Data contract on the service side is wrong
Catch ex As QuotaExceededException
'Maximum number of serializable object exceeded
Finally
target.Close()
serializer = Nothing
End Try
If you wonder when you would
need WCF serialization, there can be several answers to your question.
The most common scenarios are when you have WCF services exposing LINQ
to SQL models or Entity Data Models. Data exchange from and to clients
is performed via WCF serialization.
JSON Serialization
Starting from .NET Framework 3.5, managed languages support the JavaScript Object Notation (JSON) serialization, offered by the System.Runtime.Serialization.Json
name-space, which is particularly useful when you need to serialize
objects as javascript-compliant and that you use in WCF and ASP.NET Ajax
applications. Conceptually JSON serialization works like the WCF
serialization illustrated previously. The only difference is that you
use a DataContractJSonSerializer class that works as in the following code snippet:
Dim target As New FileStream("C:\Temp\WcfSerialized.xml", FileMode.Create)
Dim jsonSerializer As New DataContractJsonSerializer(GetType(Person))
jsonSerializer.WriteObject(target, p)
To deserialize objects you invoke the DataContractJsonSerializer.ReadObject method converting the result into the appropriate type.