At the very beginning of the ongoing work of my "Projektgruppe" we had to convert an existing XSD into a DataContract compliant schema. The XSD was part of the WSDL of one of our services which we developed using a contract-first approach. One complex type contained a xs:choice element which is not supported by DataContracts (see Data Contract Schema Reference). Therefore we decided to change our XSD. Retrospectively, maybe this was not the best decision. We discussed the usage of polymorphism with the help of xsd extension but didn't use it at all.
Nevertheless, the good old XmlSerializer supports xs:choice! Here's a very simple example:
-
using System;
-
using System.Collections.Generic;
-
using System.IO;
-
using System.Runtime.Serialization;
-
using System.ServiceModel;
-
using System.Text;
-
using System.Xml.Serialization;
-
using System.Xml;
-
using System.Xml.Schema;
-
-
namespace Choice
-
{
-
[ServiceContract(Name="ChoiceService", Namespace="http://dev.janus-net.de/example/choice")]
-
[XmlSerializerFormat(Style = OperationFormatStyle.Document)]
-
public interface IChoiceService
-
{
-
[OperationContract()]
-
void DoSomething(XSDChoice choice);
-
}
-
-
[ServiceBehavior(Name="ChoiceService", Namespace="http://dev.janus-net.de/example/choice")]
-
public class ChoiceService : IChoiceService
-
{
-
public void DoSomething(XSDChoice choice)
-
{
-
System.Console.WriteLine(choice.ToString());
-
}
-
}
-
-
[Serializable]
-
public class XSDChoice
-
{
-
-
[XmlChoiceIdentifier("ChoiceType")]
-
public object MyChoice;
-
-
[XmlIgnore]
-
[XmlElement(IsNullable=false)]
-
public ItemChoiceType ChoiceType;
-
-
public override string ToString()
-
{
-
string info = null != MyChoice ?
-
(":Type<" + MyChoice.GetType() + ">,Value<" + MyChoice.ToString() + ">")
-
: (":Type<object>,Value<null>");
-
if (ChoiceType == ItemChoiceType.Choice1)
-
{
-
return "Choice1:" + info;
-
}
-
else if (ChoiceType == ItemChoiceType.Choice2)
-
{
-
return "Choice2:" + info;
-
}
-
else
-
{
-
return info;
-
}
-
}
-
}
-
-
[XmlType(IncludeInSchema = false)]
-
public enum ItemChoiceType
-
{
-
None,
-
Choice1,
-
Choice2
-
}
-
}
This will result in the following XSD:
-
<xs:complexType name="XSDChoice">
-
<xs:sequence>
-
<xs:choice minOccurs="1" maxOccurs="1">
-
<xs:element minOccurs="1" maxOccurs="1" name="Choice2" type="xs:double"/>
-
<xs:element minOccurs="0" maxOccurs="1" name="Choice1" type="xs:string"/>
-
</xs:choice>
-
</xs:sequence>
-
</xs:complexType>
You can even do much more complex things using the XmlSerializer in conjunction with Service Contracts. Designing Service Contracts with WCF by Michele Leroux Bustamante gives a very very good introduction.