I've created a type, which implements IXmlSerializable and uses XmlSchemaProviderAttribute to define its schema, for use in a WCF service. All according "best practice"/MSDN as far as I know.
Long story short, I must use IXmlSerializable for various reasons (can't use DataContract), and I want my type to be documented in the XSD schema by using xs:annotation and xs:documentation. It seems like everything BUT the type itself can be annotated, somehow the type annotation is stripped from the schema.
Can anyone explain why, what's wrong with my code, or a working solution?
Using the class below as parameter/return value to an operation, or as part of a DataContract, correctly adds the ComplexType to the schema, with everything except the type annotation.
Specifically, this line has no effect (though with a breakpoint at the return statement, I can verify the annotation is actually there, looking correct):
type.Annotation.Items.Add(new XmlSchemaDocumentation { Markup = TextToMarkup("Documentation for MyClass") });
Full sample:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="MyNamespace" elementFormDefault="qualified" targetNamespace="MyNamespace">
<xs:complexType name="MyClass">
<xs:sequence>
<xs:element name="MyId" type="xs:integer">
<xs:annotation>
<xs:documentation>Annotation for id element</xs:documentation>
</xs:annotation>
</xs:element>
<xs:choice>
<xs:element name="MyStringChoice" type="xs:string">
<xs:annotation>
<xs:documentation>Choice number 1</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="MyIntChoice" type="xs:integer">
<xs:annotation>
<xs:documentation>Choice number 2</xs:documentation>
</xs:annotation>
</xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:element name="MyClass" nillable="true" type="tns:MyClass"/>
</xs:schema>
[XmlSchemaProvider("GenerateSchema")]
public class MyClass : IXmlSerializable
{
public static XmlQualifiedName GenerateSchema(XmlSchemaSet schemas)
{
//Create choice
var choice = new XmlSchemaChoice();
var choice1 = new XmlSchemaElement
{
Name = "MyStringChoice",
SchemaTypeName = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String).QualifiedName,
Annotation = new XmlSchemaAnnotation()
};
var choice2 = new XmlSchemaElement
{
Name = "MyIntChoice",
SchemaTypeName = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.Integer).QualifiedName,
Annotation = new XmlSchemaAnnotation()
};
choice1.Annotation.Items.Add(new XmlSchemaDocumentation { Markup = TextToMarkup("Choice number 1") });
choice2.Annotation.Items.Add(new XmlSchemaDocumentation { Markup = TextToMarkup("Choice number 2") });
choice.Items.Add(choice1);
choice.Items.Add(choice2);
//Create id element
var id = new XmlSchemaElement
{
Name = "MyId",
SchemaTypeName = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.Integer).QualifiedName,
Annotation = new XmlSchemaAnnotation()
};
id.Annotation.Items.Add(new XmlSchemaDocumentation { Markup = TextToMarkup("Annotation for id element") });
//Create sequence
var sequence = new XmlSchemaSequence();
sequence.Items.Add(id);
sequence.Items.Add(choice);
//Create type
var type = new XmlSchemaComplexType
{
Name = "MyClass",
Particle = sequence,
Annotation = new XmlSchemaAnnotation()
};
//ANNOTATE TYPE: THIS DOES NOT WORK!!!!!!!
type.Annotation.Items.Add(new XmlSchemaDocumentation { Markup = TextToMarkup("Documentation for MyClass") });
//Add type to schema
var schema = GetOrCreateSchema(schemas, "MyNamespace");
schema.Items.Add(type);
//Return XmlQualifiedName for non-anonymous types
return new XmlQualifiedName("MyClass", "MyNamespace");
}
/// <summary>
/// Create a
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
private static XmlNode[] TextToMarkup(string text)
{
var doc = new XmlDocument();
var t = doc.CreateTextNode(text);
return new XmlNode[] {t};
}
/// <summary>
/// Find schema matching the namespace, or create and add schema to set if it doesn't exist
/// </summary>
private static XmlSchema GetOrCreateSchema(XmlSchemaSet schemas, string targetNamespace)
{
var schema = schemas.Schemas(targetNamespace).OfType<XmlSchema>().FirstOrDefault();
if (schema == null)
{
schema = new XmlSchema
{
TargetNamespace = targetNamespace,
ElementFormDefault = XmlSchemaForm.Qualified
};
schemas.Add(schema);
}
return schema;
}
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
//Implementation ommited
}
public void WriteXml(XmlWriter writer)
{
//Implementation ommited
}
}