473,226 Members | 1,417 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,226 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 2826
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...
1
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
0
by: mar23 | last post by:
Here's the situation. I have a form called frmDiceInventory with subform called subfrmDice. The subform's control source is linked to a query called qryDiceInventory. I've been trying to pick up the...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
by: jimatqsi | last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....

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.