I have a third party WSDL file and XML Schema which I use to create the web service client. At large the WSDL looks as follows:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://sample.com/"
xmlns:types="http://sample.com/types"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns="http://smaple.com/types"
name="Sample"
targetNamespace="http://sample.com/">
<wsdl:types>
<xsd:schema targetNamespace="http://sample.com/types"
xmlns="http://sample.com/types">
<xsd:include schemaLocation="Sample.xsd"/>
<xsd:element name="testReq" type="TestRequestMessage">
</xsd:element>
<xsd:element name="testRes" type="TestResponseMessage">
</xsd:element>
</xsd:schema>
</wsdl:types>
<wsdl:message name="TestReqMessage">
<wsdl:part name="testReq" element="types:testReq"/>
</wsdl:message>
<wsdl:message name="TestResMessage">
<wsdl:part name="testRes" element="types:testRes"/>
</wsdl:message>
<wsdl:portType name="Test_portType">
<wsdl:operation name="TestOp">
<wsdl:input message="tns:TestReqMessage"/>
<wsdl:output message="tns:TestResMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="Test_Binding" type="tns:Test_portType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="TestOp">
<soap:operation soapAction="urn:#TestOp" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Test_XMLService">
<wsdl:port name="Test-port" binding="tns:Test_Binding">
<soap:address location="http://dummy.sample.com/Test-port"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
This is the XML schema:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://sample.com/types"
xmlns:altova="http://www.altova.com/xml-schema-extensions"
targetNamespace="http://sample.com/types"
elementFormDefault="qualified">
<!-- -->
<!--Root elements -->
<!-- -->
<xsd:element name="TestRequestMessageElement" type="TestRequestMessage">
<xsd:annotation>
<xsd:documentation>Request</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="TestResponseMessageElement" type="TestResponseMessage">
<xsd:annotation>
<xsd:documentation>Response</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- -->
<!--Complex types -->
<!-- -->
<xsd:complexType name="TestResponseMessage">
<xsd:sequence>
<xsd:element name="el1" type="Element1">
</xsd:element>
<xsd:element name="el2" type="Element2">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="TestRequestMessage">
<xsd:sequence>
<xsd:element name="el1" type="Element1">
</xsd:element>
<xsd:element name="el2" type="Element2">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Element2">
<xsd:sequence>
<xsd:element name="no1">
<xsd:simpleType>
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="0"/>
<xsd:maxInclusive value="9"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="no2">
<xsd:simpleType>
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="0"/>
<xsd:maxInclusive value="99999999"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Element1">
<xsd:sequence>
<xsd:element name="no3" minOccurs="0">
</xsd:element>
<xsd:element name="date1" type="xsd:dateTime" minOccurs="0">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
I used svcutil
to generate classes from the WSDL file with the following command: svcutil Sample.wsdl Sample.xsd
.
What I now want to do in my application is validate the object instances of these types before passing them on to a web service. I tried to do that by serializing such an instance using XmlSerializer
and performing validation using the XmlReader
:
TestRequestMessage msg = new TestRequestMessage();
msg.el1 = new ...
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(schemaName))
{
XmlSchema schema = XmlSchema.Read(stream, SchemaValidationHandler);
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add(schema);
using (MemoryStream memStream = new MemoryStream())
{
XmlSerializer ser = new XmlSerializer(typeof(RequestMessage));
ser.Serialize(memStream, msg);
memStream.Position = 0;
bool errors = false;
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas = schemas;
settings.ValidationType = ValidationType.Schema;
settings.ValidationEventHandler += (o, e) => {
// act on validation error
};
using (XmlReader reader = XmlReader.Create(memStream, settings)) {
while (reader.Read()) {}
}
The problem now is that the validation does not fail, even if I don't set all required properties or set some invalid values according to schema restrictions.
Having a closer look at the generated classes I realized that the root elements are not in the namespace they should be.
Funny enough if I run xsd.exe Sample.xsd
the generated classes are put in the correct namespace, i.e. the XmlRootAttribute is set with the correct name and namespace in contrast to the generated code using svcutil
.
What I also tried to do is reuse the generated classes from the xsd.exe
tool in my svcutil
command using the reference
switch. But this resulted in errors saying that the System.Runtime.dll
could not be found.
However what I'd like to do is create the client code including the necessary type classes with svcutil
. How can I do that correctly?
Any help is greatly appreciated.