473,386 Members | 1,820 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Problem generating client proxy with complex return types

Dear all,
I am having trouble generating a client proxy for a webservice whose
methods return a "complex" type. The type is complex in that it is a
class whose members are a mix of primitive types and of more elaborate
classes implementing IXmlSerializable. The resulting WSDL file for the
webservice has two separate schemas in its <types> sections, and the
client proxy (generated with wsdl.exe) is missing the definitions of
the IXmlSerializable types. More details follow.

I could reproduce the problem with a simple example. The webservice is
called WSTest.Service1 @ http://localhost/WSTest/Service1.asmx, and it
has a method called HelloWorld.
Here is the Service1.asmx file (hope the formatting won't go wild):
------------------------------------------------
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Schema;

namespace WSTest
{
// This is the IXmlSerializable derivative, member of the webmethod's
actual return type
public class WSTestDetail: IXmlSerializable
{
// Class data
public string Code;
public string Description;

// IXmlSerializable implementation
public void WriteXml (XmlWriter writer)
{
// ...
}

public void ReadXml (XmlReader reader)
{
// ...
}

public XmlSchema GetSchema ()
{
XmlSchemaSequence seq = new XmlSchemaSequence ();
XmlSchemaElement element;

element = new XmlSchemaElement ();
element.Name = "Code";
element.SchemaTypeName = new XmlQualifiedName ("string",
"http://www.w3.org/2001/XMLSchema");
element.MinOccurs = 0;
element.MaxOccurs = 1;
seq.Items.Add (element);

element = new XmlSchemaElement ();
element.Name = "Description";
element.SchemaTypeName = new XmlQualifiedName ("string",
"http://www.w3.org/2001/XMLSchema");
element.MinOccurs = 0;
element.MaxOccurs = 1;
seq.Items.Add (element);

XmlSchemaComplexType type = new XmlSchemaComplexType ();
type.Particle = seq;
type.Name = "WSTestDetailType";

XmlSchemaElement root = new XmlSchemaElement ();
root.Name = "WSTestDetail";
root.SchemaTypeName = new XmlQualifiedName ("WSTestDetailType",
"http://www.testme.org/types");

XmlSchema schema = new XmlSchema ();
schema.Id = "WSTestDetailSchema";
schema.TargetNamespace = "http://www.testme.org/types";

schema.Namespaces.Add ("xs", "http://www.w3.org/2001/XMLSchema");

schema.Items.Add (type);
schema.Items.Add (root);

return schema;
}
}

// This is the return type of the webmethod
public class WSTestResult
{
public WSTestDetail Detail;
public string Status;
}

/// <summary>
/// Summary description for Service1.
/// </summary>
[WebService(Namespace="http://www.testme.org/ws")]
public class Service1 : System.Web.Services.WebService
{
public Service1()
{
InitializeComponent();
}

#region Component Designer generated code
// ...
#endregion

[WebMethod]
public WSTestResult HelloWorld()
{
return new WSTestResult ();
}
}
}
------------------------------------------------

The WSDL document (Service1.wsdl):
------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:s1="http://www.testme.org/types"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://www.testme.org/ws"
xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
targetNamespace="http://www.testme.org/ws"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified"
targetNamespace="http://www.testme.org/ws">
<s:import namespace="http://www.testme.org/types" />
<s:element name="HelloWorld">
<s:complexType />
</s:element>
<s:element name="HelloWorldResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1"
name="HelloWorldResult" type="tns:WSTestResult" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="WSTestResult">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Detail">
<s:complexType>
<s:sequence>
<s:any namespace="http://www.testme.org/types" />
</s:sequence>
</s:complexType>
</s:element>
<s:element minOccurs="0" maxOccurs="1" name="Status"
type="s:string" />
</s:sequence>
</s:complexType>
</s:schema>
<s:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.testme.org/types" id="WSTestDetailSchema">
<xs:complexType name="WSTestDetailType">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="Code"
type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="Description"
type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:element name="WSTestDetail" type="s1:WSTestDetailType" />
</s:schema>
</wsdl:types>
<wsdl:message name="HelloWorldSoapIn">
<wsdl:part name="parameters" element="tns:HelloWorld" />
</wsdl:message>
<wsdl:message name="HelloWorldSoapOut">
<wsdl:part name="parameters" element="tns:HelloWorldResponse" />
</wsdl:message>
<wsdl:portType name="Service1Soap">
<wsdl:operation name="HelloWorld">
<wsdl:input message="tns:HelloWorldSoapIn" />
<wsdl:output message="tns:HelloWorldSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="Service1Soap" type="tns:Service1Soap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document" />
<wsdl:operation name="HelloWorld">
<soap:operation soapAction="http://www.testme.org/ws/HelloWorld"
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="Service1">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/" />
<wsdl:port name="Service1Soap" binding="tns:Service1Soap">
<soap:address location="http://localhost/WSTest/Service1.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
------------------------------------------------

As you can see, with WSTestDetail providing its own GetSchema()
implementation, we have 2 <schema>'s in the WSDL.
WSTestResult.Detail has a strange declaration: instead of the expected
<s:element name="Detail" type="s1:WSTestDetailType">, I get a
complexType/sequence/any specification. Why not; the 2nd schema has
only one toplevel element so I guess that's fine and leads to no
ambiguities.
Now the client proxy (wsdl.exe Service1.wsdl):
------------------------------------------------
using System.Diagnostics;
using System.Xml.Serialization;
using System;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Web.Services;
/// <remarks/>
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("c ode")]
[System.Web.Services.WebServiceBindingAttribute(Nam e="Service1Soap",
Namespace="http://www.testme.org/ws")]
public class Service1 :
System.Web.Services.Protocols.SoapHttpClientProtoc ol {

/// <remarks/>
public Service1() {
this.Url = "http://localhost/WSTest/Service1.asmx";
}

/// <remarks/>

[System.Web.Services.Protocols.SoapDocumentMethodAt tribute("http://www.testme.org/ws/HelloWorld",
RequestNamespace="http://www.testme.org/ws",
ResponseNamespace="http://www.testme.org/ws",
Use=System.Web.Services.Description.SoapBindingUse .Literal,
ParameterStyle=System.Web.Services.Protocols.SoapP arameterStyle.Wrapped)]
public WSTestResult HelloWorld() {
object[] results = this.Invoke("HelloWorld", new object[0]);
return ((WSTestResult)(results[0]));
}

/// <remarks/>
public System.IAsyncResult BeginHelloWorld(System.AsyncCallback
callback, object asyncState) {
return this.BeginInvoke("HelloWorld", new object[0], callback,
asyncState);
}

/// <remarks/>
public WSTestResult EndHelloWorld(System.IAsyncResult asyncResult)
{
object[] results = this.EndInvoke(asyncResult);
return ((WSTestResult)(results[0]));
}
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(Namespac e="http://www.testme.org/ws")]
public class WSTestResult {

/// <remarks/>
public WSTestDetailSchema Detail;

/// <remarks/>
public string Status;
}
------------------------------------------------

WSTestResult.Detail's type is named WSTestDetailSchema (I would have
expected WSTestDetailType), but again, why not. The missing type
declaration for WSTestDetailSchema is much more annoying as this makes
the WSDL useless for clients.

Is there any reason why this is happening? Why do I have 2 schemas in
my WSDL? How can I ask that WSTestResult.Detail be of type
s1:WSTestDetailType in the WSDL? Since the class in Service1.asmx
implements IXmlSerializable, I cannot use Xml serialization attributes
like XmlType. The interface is needed because we want to have fine
control on the serialization.
I hope the question is not too stupid. The thing is, I'm not too
familiar with schemas, namespaces and such. Also, we're in 1.1 and
IXmlSerializable is not very well documented.

Thanks in advance!

Best regards,
Thomas

Feb 22 '06 #1
1 2833
Seems that wsdl.exe does not like IXmlSerializable. I could get around
this by intercepting the "?wsdl" call in Application_BeginRequest (),
getting the incorrect ServiceDescription from there (with
ServiceDescriptionReflector), and altering
ServiceDescription.Types.Schemas.
The idea is to collapse all schemas therein into the first one, replace
the complexType/sequence/any with a type="..." attribute, and fix up
all namespaces references.

Not very elegant but it works very well... Also, the default
documentation/test page for the service is not affected, as would have
been the case if I had added a <wsdlHelpGenerator> tag in Web.config.

Thomas

Feb 24 '06 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: raymond | last post by:
Hi, Is it possible to create a proxy client class or a web service method by VS.NET without using wsdl? My stupid client is using a xml schema (.xsd) to describe all their web service methods...
4
by: Flare | last post by:
OK. I'll try explain my problem so simple as possible. I have to send a complex data type to a WebService from a Asp.net webapplication. My Data type look like this. (A class with a porperty)...
3
by: Ohad Young | last post by:
Hi, I have a webservice method that returns an instance of a custom class I created (e.g., bank account). The class definition in the webservice contains properties, overrides Object.ToString...
2
by: yqlu | last post by:
I hava developed a client in C# that is connected to a 3-party XML Web Services developed in Java based on the AXIS 1.1. Most methods call are successful except for one method named "findObjects"...
7
by: Nalaka | last post by:
Hi, I created a sinple web service that returns a dataSet. Then I created a client program that uses this web service (that returns the Dataset). My question is, how did the client figure...
1
by: J. Askey | last post by:
I am implementing a web service and thought it may be a good idea to return a more complex class (which I have called 'ServiceResponse') in order to wrap the original return value along with two...
3
by: kkao77 | last post by:
I am trying to use schema to validate the data that user sent to my service. How do I achieve that using schema? Do I give schema to the client? or do I write my own schema validation inside web...
13
by: John Kotuby | last post by:
I am expecting the answer to be, "of course not" or " are you kidding?", but maybe (hopefully) I am wrong and somebody can point me to an ingenious example of how the impossible just takes a little...
0
by: RobR2009 | last post by:
I am having trouble with a C# proxy page I am writing which allows me to do cross domain AJAX calls with Javascript. The problem is with certain pages that contain pound signs £ that are not HTML...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.