Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

web-service methods with variable quantity of income parameters

3 views
Skip to first unread message

Evgenia

unread,
Nov 3, 2004, 5:11:03 AM11/3/04
to
There are two methods in my web service:
1. public XmlDocument MethodName1(string MethodStringParam, params int[]
MethodIntParams)
2. public void MethodName2(XmlNode MethodNodeParam, string
MethodStringParam, string MethodString2Param, params object[] MethodObjParams)

Both of them can take (owing to using params) variable quantity of income
parameters.

Then I use these methods inside other methods of that web service, they
successfully work. For example, I can invoke method as
MethodName1("StringHere") and as MethodName1("StringHere",25).

Now I need to invoke methods on client side. And unfortunately with
MethodName1("StringHere") I receive the error:
No overload for method 'MethodName1' takes '1' arguments

What is my mistake?
And how can I use methods with params on clien side? What should I do?

I expect your help impatiently.

Dino Chiesa [Microsoft]

unread,
Nov 3, 2004, 10:48:02 AM11/3/04
to
use a message Schema that has optional extensions in it.

For example:
[webmethod] MyMethod (IncomingMessage m) {
...
}

where IncomingMessage is defined in a W3C XML Schema to include numerous
fields, all of which are optional. In C# or VB, it would be a struct or
class with numerous properties, not all of which need to be set (or passed).

Variable param lists is a function-call concept. For web services, you have
to think "message passing", not "remote function call". You don't pass
"variable parameter lists" to a webmethod, you pass a message, with varying
content within it.

-D


"Evgenia" <Evg...@discussions.microsoft.com> wrote in message
news:FA50226F-CF39-43FD...@microsoft.com...

Evgenia

unread,
Nov 4, 2004, 3:45:01 AM11/4/04
to
"Dino Chiesa [Microsoft]" wrote:
> use a message Schema that has optional extensions in it.
> For example:
> [webmethod] MyMethod (IncomingMessage m) {

I nearly understand your idea. But, please, may I ask you for a simple
example of IncomingMessage class?

Evgenia

unread,
Nov 4, 2004, 3:48:02 AM11/4/04
to
> [webmethod] MyMethod (IncomingMessage m) {

And one more question - what will be the invoke of such method? How will it
look like? For me it's very important to use invokes like:
MyMethod(param1)
MyMethod(param1,param2)
MyMethod(param1,param2,param3)
Is it possible?

Dino Chiesa [Microsoft]

unread,
Nov 4, 2004, 9:57:49 AM11/4/04
to
> I nearly understand your idea.

here is a great article covering the topic:
http://www.webservices.org/index.php/ws/content/view/full/39565

> please, may I ask you for a simple example of IncomingMessage class?

The way I do it: construct a W3C XML Schema describing the datatype, then
generate types for that Schema, specific to each platform. Let's suppose
you have a .NET and a Java system inter-connecting via webservices. A
request message gets passed from requester to receiver - it does not matter
which one is which. The message might include an order ID, a priority, some
authentication information, and a conversation ID. In response, optionally
a Response Message gets passed back. [in one-way web service requests,
there is no response message]. In C# code you might code something like
this series of classes:

public enum PriorityLevel {
Normal=0,
High=1,
Urgent=2,
Lazy=3
}

// this is the request message
public class RequestMessage1 {
public int orderID;
public PriorityLevel priority;
public string OnBehalfOf;
public int conversationID;
}

public class Order {
public int ID;
public int customerID;
// public OrderItems[] i;
// etc
}

public enum Confidence {
High,
Normal,
Low

}

// this is the response message
public class ResponseMessage {
public Order o;
public Confidence c;
// etc
}

By compiling this C# code into a DLL, then running xsd.exe on the resulting
DLL, you can develop an XSD that describes these types. It looks like
this:

<xs:schema elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="PriorityLevel" type="PriorityLevel" />
<xs:simpleType name="PriorityLevel">
<xs:restriction base="xs:string">
<xs:enumeration value="Normal" />
<xs:enumeration value="High" />
<xs:enumeration value="Urgent" />
<xs:enumeration value="Lazy" />
</xs:restriction>
</xs:simpleType>
<xs:element name="RequestMessage1" nillable="true" type="RequestMessage1"
/>
<xs:complexType name="RequestMessage1">
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="orderID" type="xs:int"
/>
<xs:element minOccurs="1" maxOccurs="1" name="priority"
type="PriorityLevel" />
<xs:element minOccurs="0" maxOccurs="1" name="OnBehalfOf"
type="xs:string" />
<xs:element minOccurs="1" maxOccurs="1" name="conversationID"
type="xs:int" />
</xs:sequence>
</xs:complexType>
<xs:element name="Order" nillable="true" type="Order" />
<xs:complexType name="Order">
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="ID" type="xs:int" />
<xs:element minOccurs="1" maxOccurs="1" name="customerID"
type="xs:int" />
</xs:sequence>
</xs:complexType>
<xs:element name="Confidence" type="Confidence" />
<xs:simpleType name="Confidence">
<xs:restriction base="xs:string">
<xs:enumeration value="High" />
<xs:enumeration value="Normal" />
<xs:enumeration value="Low" />
</xs:restriction>
</xs:simpleType>
<xs:element name="ResponseMessage" nillable="true" type="ResponseMessage"
/>
<xs:complexType name="ResponseMessage">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="o" type="Order" />
<xs:element minOccurs="1" maxOccurs="1" name="c" type="Confidence" />
</xs:sequence>
</xs:complexType>
</xs:schema>

You can now modify, adjust, tweak, or extend this XSD. [The alternative is
to simply write XSD from the beginning, without prototyping the messages in
C#. If you are fluent in XSD or have tools like XmlSpy, then go for it!
But not all people "think in XSD". ]

At some point you will be happy with your schema definition. Take this
schema and then generate platform-specific types with it. Also, import
this XSD into the web service interface definition (WSDL).
http://devresource.hp.com/drc/slide_presentations/schemaWSDL/index.jsp

Then generate proxy classes (stubs) for the client from this WSDL. Also
generate server-side skeleton classes for the server from the same WSDL.
This approach of designing the datatypes and interface and deriving or
generating the implementation skeleton from those definitions is called
"WSDL first" or sometimes "contract first" design.
http://www.google.com/search?hl=en&num=30&q="contract+first"+"web+services"

In your case you have fields like param1, param2, param3, etc. It will look
like this in (generated) C# code:

public class RequestMessage1 {
public int param1;
public string param2,
public MyCustomDataType param3;
// etc
}

(NB: the actual code will be attributed with XmlSerialization attributes).

The requester application can then instantiate the RequestMessage1,
optionally fill or set the fields as necessary, and then invoke the service.
Like so:

// get a proxy to the remote webservice
MyNamespace.MyWebService svc= new MyNamespace.MyWebService () ;

// instantiate and fill the request
MyNamespace.RequestMessage1 m = MyNamespace.RequestMessage1 () ;
m.param1= 42;
if (some condition) m.param2= "Contract First";
if (I feel like it) m.param3= new MyCustomDataType(....) ;

// invoke (implicitly passing the request message)
MyNamespace.ResponseMessage1 r = svc.MyMethod(m);


The request and response messages are always the same type, but the fields
within them may be optionally set, or not. On the server side, the code
can behave differently depending on the content of the incoming request
message.


-Dino

--
Dino Chiesa
Microsoft Developer Division
d i n o c h @ OmitThis . m i c r o s o f t . c o m


"Evgenia" <Evg...@discussions.microsoft.com> wrote in message

news:16F5645F-8B6F-452E...@microsoft.com...

No. Well, it is possible, but it goes counter to my advice of using a
message-passing model.


bwmbagus

unread,
Nov 7, 2004, 12:30:02 PM11/7/04
to
The problem is about overloading, since you cannot expose overloaded
functions as web services.
It would not be impossible for Microsoft to make this possible.
Howvere, as is mentioned, we are passing and receiving messages, and we have
no stack or heap to help us.
If overeloading is not what you seek, but you want a call like
datatype function("param1=xxx","param99=yyyy",...)
then put you parameters in an xmldocument, and pass that in. This means you
need to pare the xmldocument to get the data out and set it up for the
function, but XML is universal.
Then you use one parameter for the body of data.
It is easy to construct XML in javascript etc on the client so I have always
used this technique, since 1999 when XML started to show its head properly.
This also means never having to change the signeture of your web servicer,
and acts as a great single entry point to a range of services configured by
XML 'documents' passed as paramters.
In essence, this is what Dino is too busy to explain fully.
Bwmbagus
0 new messages