Class Program
Shared Sub Main(ByVal args() As String)
' Create and populate an Employee instance.
Dim emp As New Employee()
emp.date_hired = New DateTime(1999, 10, 14)
emp.salary = 33000
' Note that the Person class is a legacy XmlSerializable class
' without a DataContract.
emp.person = New Person()
emp.person.first_name = "Mike"
emp.person.last_name = "Ray"
emp.person.age = 44
' Create a serializer.
Dim ser As New DataContractSerializer(GetType(Employee))
' Attempt to serialize without a surrogate. (This will fail.)
Console.WriteLine(" Attempting to serialize without a surrogate: " + vbLf)
Dim fileName As String = "surrogateEmployee.xml"
Dim fs As New FileStream(fileName, FileMode.Create)
Dim writer As XmlDictionaryWriter = XmlDictionaryWriter.CreateTextWriter(fs)
Try
ser.WriteObject(writer, emp)
writer.Flush()
writer.Close()
Catch
writer.Flush()
Console.Write(writer.ToString())
Console.WriteLine(vbLf + vbLf + _
" Cannot serialize without a surrogate since Person has no DataContract " + vbLf)
End Try
' Close the writer objects after failing to serialize.
writer.Close()
fs.Close()
Console.WriteLine(" Now use a surrogate for the Person class and try again")
' Create a new instance of the serializer. The
' constructor demands a knownTypes and surrogate.
' Create a Generic List for the knownTypes. Then create an
' instance of the surrogate class (defined below).
Dim knownTypes As List(Of Type) = New List(Of Type)()
Dim sur As New LegacyPersonTypeSurrogate()
Dim surrogateSerializer As New _
DataContractSerializer(GetType(Employee), _
knownTypes, Integer.MaxValue, False, True, sur)
' Create a new writer. Then serialize with the
' surrogate serializer.
Dim newFs As New FileStream(fileName, FileMode.Create)
Dim newWriter As XmlDictionaryWriter = XmlDictionaryWriter.CreateTextWriter(newFs)
Try
surrogateSerializer.WriteObject(newWriter, emp)
Console.Write(newWriter.ToString())
Console.WriteLine("Serialization succeeded. Now doing deserialization.")
newWriter.Close()
newFs.Close()
Catch
Console.WriteLine(" We never get here")
End Try
' Create a new reader object.
Dim fs2 As New FileStream(fileName, FileMode.Open)
Dim reader As XmlDictionaryReader = _
XmlDictionaryReader.CreateTextReader(fs2, New XmlDictionaryReaderQuotas())
Console.WriteLine("Trying to deserialize with surrogate.")
Try
Dim newemp As Employee = CType _
(surrogateSerializer.ReadObject(reader, False), Employee)
reader.Close()
fs2.Close()
Console.WriteLine("Deserialization succeeded. " + vbLf + vbLf)
Console.WriteLine("Deserialized Person data: " + vbLf + vbTab + _
" {0} {1}", newemp.person.first_name, newemp.person.last_name)
Console.WriteLine(vbTab + " Age: {0} " + vbLf, newemp.person.age)
Catch serEx As SerializationException
Console.WriteLine(serEx.Message)
Console.WriteLine(serEx.StackTrace)
End Try
Console.WriteLine("Now doing schema export/import.")
' The following code demonstrates schema export with a surrogate.
' The surrogate indicates how to export the non-DataContract Person type.
' Without the surrogate, schema export would fail.
Dim xsdexp As New XsdDataContractExporter()
xsdexp.Options = New ExportOptions()
xsdexp.Options.DataContractSurrogate = New LegacyPersonTypeSurrogate()
xsdexp.Export(GetType(Employee))
' Write out the exported schema to a file.
Dim fs3 As New FileStream("sample.xsd", FileMode.Create)
Try
Dim sch As XmlSchema
For Each sch In xsdexp.Schemas.Schemas()
sch.Write(fs3)
Next sch
Finally
fs3.Dispose()
End Try
' The following code demonstrates schema import with
' a surrogate. The surrogate is used to indicate that
' the Person class already exists and that there is no
' need to generate a new class when importing the
' PersonSurrogated data contract. If the surrogate
' was not used, schema import would generate a
' PersonSurrogated class, and the person field
' of Employee would be imported as
' PersonSurrogated and not Person.
Dim xsdimp As New XsdDataContractImporter()
xsdimp.Options = New ImportOptions()
xsdimp.Options.DataContractSurrogate = New LegacyPersonTypeSurrogate()
xsdimp.Import(xsdexp.Schemas)
' Write out the imported schema to a C-Sharp file.
Dim fs4 As FileStream = New FileStream("sample.cs", FileMode.Create)
Try
Dim tw As New StreamWriter(fs4)
Dim cdp As New Microsoft.CSharp.CSharpCodeProvider()
cdp.GenerateCodeFromCompileUnit(xsdimp.CodeCompileUnit, tw, Nothing)
tw.Flush()
Finally
fs4.Dispose()
End Try
Console.WriteLine(vbLf + " To see the results of schema export and import,")
Console.WriteLine(" see SAMPLE.XSD and SAMPLE.CS." + vbLf)
Console.WriteLine(" Press ENTER to terminate the sample." + vbLf)
Console.ReadLine()
End Sub
End Class
' This is the Employee (outer) type used in the sample.
<DataContract()> _
Class Employee
<DataMember()> _
Public date_hired As DateTime
<DataMember()> _
Public salary As [Decimal]
<DataMember()> _
Public person As Person
End Class
' This is the Person (inner) type used in the sample.
' Note that it is a legacy XmlSerializable type and not a DataContract type.
Public Class Person
<XmlElement("FirstName")> _
Public first_name As String
<XmlElement("LastName")> _
Public last_name As String
<XmlAttribute("Age")> _
Public age As Integer
Public Sub New()
End Sub
End Class
' This is the surrogated version of the Person type
' that will be used for its serialization/deserialization.
<DataContract()> _
Class PersonSurrogated
' xmlData will store the XML returned for a Person instance
' by the XmlSerializer.
<DataMember()> _
Public xmlData As String
End Class
' This is the surrogate that substitutes PersonSurrogated for Person.
Class LegacyPersonTypeSurrogate
Implements IDataContractSurrogate
Public Function GetDataContractType(ByVal type As Type) As Type _
Implements IDataContractSurrogate.GetDataContractType
' "Person" will be serialized as "PersonSurrogated"
' This method is called during serialization,
' deserialization, and schema export.
If GetType(Person).IsAssignableFrom(type) Then
Return GetType(PersonSurrogated)
End If
Return type
End Function
Public Function GetObjectToSerialize(ByVal obj As Object, _
ByVal targetType As Type) As Object _
Implements IDataContractSurrogate.GetObjectToSerialize
' This method is called on serialization.
' If Person is not being serialized...
If TypeOf obj Is Person Then
' ... use the XmlSerializer to perform the actual serialization.
Dim ps As New PersonSurrogated()
Dim xs As New XmlSerializer(GetType(Person))
Dim sw As New StringWriter()
xs.Serialize(sw, CType(obj, Person))
ps.xmlData = sw.ToString()
Return ps
End If
Return obj
End Function
Public Function GetDeserializedObject(ByVal obj As Object, _
ByVal targetType As Type) As Object Implements _
IDataContractSurrogate.GetDeserializedObject
' This method is called on deserialization.
' If PersonSurrogated is not being deserialized...
If TypeOf obj Is PersonSurrogated Then
'... use the XmlSerializer to do the actual deserialization.
Dim ps As PersonSurrogated = CType(obj, PersonSurrogated)
Dim xs As New XmlSerializer(GetType(Person))
Return CType(xs.Deserialize(New StringReader(ps.xmlData)), Person)
End If
Return obj
End Function
Public Function GetReferencedTypeOnImport(ByVal typeName As String, _
ByVal typeNamespace As String, ByVal customData As Object) As Type _
Implements IDataContractSurrogate.GetReferencedTypeOnImport
' This method is called on schema import.
' If a PersonSurrogated data contract is
' in the specified namespace, do not create a new type for it
' because there is already an existing type, "Person".
If typeNamespace.Equals("http://schemas.datacontract.org/2004/07/DCSurrogateSample") Then
If typeName.Equals("PersonSurrogated") Then
Return GetType(Person)
End If
End If
Return Nothing
End Function
Public Function ProcessImportedType(ByVal typeDeclaration _
As System.CodeDom.CodeTypeDeclaration, _
ByVal compileUnit As System.CodeDom.CodeCompileUnit) _
As System.CodeDom.CodeTypeDeclaration _
Implements IDataContractSurrogate.ProcessImportedType
' Not used in this sample.
' You could use this method to construct an entirely new CLR
' type when a certain type is imported, or modify a
' generated type in some way.
Return typeDeclaration
End Function
Overloads Public Function GetCustomDataToExport _
(ByVal clrType As Type, ByVal dataContractType As Type) As Object _
Implements IDataContractSurrogate.GetCustomDataToExport
' Not used in this sample
Return Nothing
End Function
Overloads Public Function GetCustomDataToExport _
(ByVal memberInfo As System.Reflection.MemberInfo, _
ByVal dataContractType As Type) As Object _
Implements IDataContractSurrogate.GetCustomDataToExport
' Not used in this sample
Return Nothing
End Function
Public Sub GetKnownCustomDataTypes(ByVal customDataTypes As Collection(Of Type)) _
Implements IDataContractSurrogate.GetKnownCustomDataTypes
' Not used in this sample
End Sub
End Class