방법: WCF 응용 프로그램의 메시지 serialize
업데이트: 2007년 11월
.NET Compact Framework 버전 3.5에서는 WCF(Windows Communication Foundation) 응용 프로그램에서 메시지의 serialization 및 deserialization에 대한 지원을 구현하는 데 사용될 수 있는 XmlObjectSerializer 클래스를 추가로 지원합니다.
예제
다음 코드 예제에서는 XmlObjectSerializer를 구현하고 장치와 데스크톱 모두에서 메시지를 serialize 및 deserialize하는 데 사용될 수 있는 CFMessagingSerializer라는 클래스를 보여 줍니다.
Public Class CFMessagingSerializer
Inherits XmlObjectSerializer
Private objectType As Type
Private serializer As XmlSerializer
Public Sub New(ByVal objectType As Type)
Me.New(objectType, Nothing, Nothing)
End Sub
Public Sub New(ByVal objectType As Type, ByVal wrapperName As String, ByVal wrapperNamespace As String)
MyBase.New()
If (objectType Is Nothing) Then
Throw New ArgumentNullException("objectType")
End If
If ((wrapperName Is Nothing) _
<> (wrapperNamespace = Nothing)) Then
Throw New ArgumentException("wrapperName and wrapperNamespace must be either both null or both non-null.")
End If
If (wrapperName = String.Empty) Then
Throw New ArgumentException("Cannot be the empty string.", "wrapperName")
End If
Me.objectType = objectType
If (Not (wrapperName) Is Nothing) Then
Dim root As XmlRootAttribute = New XmlRootAttribute(wrapperName)
root.Namespace = wrapperNamespace
Me.serializer = New XmlSerializer(objectType, root)
Else
Me.serializer = New XmlSerializer(objectType)
End If
End Sub
Public Overrides Function IsStartObject(ByVal reader As XmlDictionaryReader) As Boolean
Throw New NotImplementedException
End Function
Public Overrides Function ReadObject(ByVal reader As XmlDictionaryReader, ByVal verifyObjectName As Boolean) As Object
Debug.Assert((Not (serializer) Is Nothing))
If (reader Is Nothing) Then
Throw New ArgumentNullException("reader")
End If
If Not verifyObjectName Then
Throw New NotSupportedException
End If
Return serializer.Deserialize(reader)
End Function
Public Overrides Sub WriteStartObject(ByVal writer As XmlDictionaryWriter, ByVal graph As Object)
Throw New NotImplementedException
End Sub
Public Overrides Sub WriteObjectContent(ByVal writer As XmlDictionaryWriter, ByVal graph As Object)
If (writer Is Nothing) Then
Throw New ArgumentNullException("writer")
End If
If (writer.WriteState <> WriteState.Element) Then
Throw New SerializationException(String.Format("WriteState '{0}' not valid. Caller must write start element before serializing in contentOnly mode.", writer.WriteState))
End If
Dim memoryStream As MemoryStream = New MemoryStream
Dim bufferWriter As XmlDictionaryWriter = XmlDictionaryWriter.CreateTextWriter(memoryStream, Encoding.UTF8)
serializer.Serialize(bufferWriter, graph)
bufferWriter.Flush()
memoryStream.Position = 0
Dim reader As XmlReader = New XmlTextReader(memoryStream)
reader.MoveToContent()
writer.WriteAttributes(reader, False)
If reader.Read Then
While (reader.NodeType <> XmlNodeType.EndElement)
writer.WriteNode(reader, False)
End While
' this will take us to the start of the next child node, or the end node.
reader.ReadEndElement()
' not necessary, but clean
End If
End Sub
Public Overrides Sub WriteEndObject(ByVal writer As XmlDictionaryWriter)
Throw New NotImplementedException
End Sub
Public Overrides Sub WriteObject(ByVal writer As XmlDictionaryWriter, ByVal graph As Object)
Debug.Assert((Not (serializer) Is Nothing))
If (writer Is Nothing) Then
Throw New ArgumentNullException("writer")
End If
serializer.Serialize(writer, graph)
End Sub
End Class
public class CFMessagingSerializer : XmlObjectSerializer
{
readonly Type objectType;
XmlSerializer serializer;
public CFMessagingSerializer(Type objectType)
: this(objectType, null, null)
{
}
public CFMessagingSerializer(Type objectType, string wrapperName, string wrapperNamespace)
{
if (objectType == null)
throw new ArgumentNullException("objectType");
if ((wrapperName == null) != (wrapperNamespace == null))
throw new ArgumentException("wrapperName and wrapperNamespace must be either both null or both non-null.");
if (wrapperName == string.Empty)
throw new ArgumentException("Cannot be the empty string.", "wrapperName");
this.objectType = objectType;
if (wrapperName != null)
{
XmlRootAttribute root = new XmlRootAttribute(wrapperName);
root.Namespace = wrapperNamespace;
this.serializer = new XmlSerializer(objectType, root);
}
else
this.serializer = new XmlSerializer(objectType);
}
public override bool IsStartObject(XmlDictionaryReader reader)
{
throw new NotImplementedException();
}
public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
{
Debug.Assert(serializer != null);
if (reader == null) throw new ArgumentNullException("reader");
if (!verifyObjectName)
throw new NotSupportedException();
return serializer.Deserialize(reader);
}
public override void WriteStartObject(XmlDictionaryWriter writer, object graph)
{
throw new NotImplementedException();
}
public override void WriteObjectContent(XmlDictionaryWriter writer, object graph)
{
if (writer == null) throw new ArgumentNullException("writer");
if (writer.WriteState != WriteState.Element)
throw new SerializationException(string.Format("WriteState '{0}' not valid. Caller must write start element before serializing in contentOnly mode.",
writer.WriteState));
using (MemoryStream memoryStream = new MemoryStream())
{
using (XmlDictionaryWriter bufferWriter = XmlDictionaryWriter.CreateTextWriter(memoryStream, Encoding.UTF8))
{
serializer.Serialize(bufferWriter, graph);
bufferWriter.Flush();
memoryStream.Position = 0;
using (XmlReader reader = new XmlTextReader(memoryStream))
{
reader.MoveToContent();
writer.WriteAttributes(reader, false);
if (reader.Read()) // move off start node (we want to skip it)
{
while (reader.NodeType != XmlNodeType.EndElement) // also skip end node.
writer.WriteNode(reader, false); // this will take us to the start of the next child node, or the end node.
reader.ReadEndElement(); // not necessary, but clean
}
}
}
}
}
public override void WriteEndObject(XmlDictionaryWriter writer)
{
throw new NotImplementedException();
}
public override void WriteObject(XmlDictionaryWriter writer, object graph)
{
Debug.Assert(serializer != null);
if (writer == null) throw new ArgumentNullException("writer");
serializer.Serialize(writer, graph);
}
}
코드 컴파일
이 예제에는 다음과 같은 네임스페이스에 대한 참조가 필요합니다.
참고 항목
기타 리소스
WCF(Windows Communication Foundation) 개발 및 .NET Compact Framework