WCF, NuSOAP and ArrayOfString
When exposing a WebService via WCF, you might want to expose something like this :
[code:c#][DataContract]
public class SomeContract
{
[DataMember]
public string[] Values { get; set; }
}
[/code]
For that particular data contract, WCF will be generating a WSDL with something like this :
[code:xml]
<xs:complexType name="SomeContract">
<xs:sequence>
<xs:element minOccurs="0" name="Values" nillable="true"
type="q1:ArrayOfstring"
xmlns:q1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
</xs:sequence>
</xs:complexType>
[/code]
With ArrayOfString being defined like this :
[code:xml]
<xs:schema elementFormDefault="qualified"
targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<xs:complexType name="ArrayOfstring">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfstring" nillable="true" type="tns:ArrayOfstring"/>
</xs:schema>
[/code]
In general, that would be fine. The type "ArrayOfString" is defined in a different namespace, but this should not be a problem.
So, to use that particular type in a method call, you should have a document like this one :
[code:xml]
<SomeContract>
<Values xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<a:string>My Value</a:string>
</Values>
</SomeContract>
[/code]
"string" elements are contained in a different namespace from the SomeContract element. However, the NuSOAP stock version 0.7.2 has a problem with that kind of schema, and generates instead something like this :
[code:xml]
<SomeContract>
<Values>
<string>My Value</string>
</Values>
</SomeContract>
[/code]
Since there's no way of fixing NuSOAP, you may need to tweak your contract to help NuSOAP serializing your data without a namespace.
The CollectionDataContract attribute seems to be the way to go, since there is a way to specify the namespace to use when generating the metadata. The service contract then looks like this :
[code:c#]
[DataContract(Namespace = "http://my.name.space")]
public class SomeContract
{
[DataMember]
public ArrayOfString InvalidIdentifiers { get; set; }
}
[CollectionDataContract(ItemName="string", Namespace="http://my.name.space")]
public class ArrayOfString : List<string> { }
[/code]
Thereby placing everything in the "http://my.name.space" namespace.
You might need to tweak a bit the ArrayOfString class, especially if you need to assign it from an actual string[] instance, but you get the idea.