2006-11-02 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.Web.Services / System.Web.Services.Protocols / NOTES
1 Notes on the Soap Client
2 ------------------------
3
4 * Preparing an invocation.
5
6         To send a SOAP request to a remote server, applications will
7         instantiate a class created by the WSDL compiler that derives
8         from SoapHttpClientProtocol.
9
10         The classes generated are fairly simple, they contain stubs
11         for all of the methods generated just pass the name of the
12         method and the arguments they receive to the protected
13         Invoke() method on SoapHttpClientProtocol.
14
15         To invoke a method on a SOAP server it is necessary to
16         instantiate the generated class, and possibly configure the
17         Url property of it (to point to the right server) and then
18         invoking the stubs. 
19
20         SoapHttpClientProtocol will create a SoapClientMessage based
21         on this information.  The SoapClientMessage class is used to
22         pass the information to hooks or extensions in the .NET
23         Framework.  These hooks are invoked at various phases to
24         customize the SOAP message. 
25
26         For the first pass of our implementation, we will not invoke
27         any of those hooks.  They are required for things like WSS,
28         but we do not need this now.
29
30         A WebRequest object of type POST is created, and we will use
31         this to send our Soap message. 
32
33 * Creating the SOAP request
34
35         The SOAP request is fairly simple;   For our initial
36         implementation we will only support the schema encoding. 
37
38         For each stub method, we need to create an XmlSerializer for
39         the parameter values, and another one for the return value.
40
41         The encoding is fairly simple, see the post on
42         mono-serialization-list for a sample program.
43
44 * Processing the return value.
45
46         Soon.
47
48 * Metadata
49
50         Methods.cs extracts class and method information: it basically
51         pulls all the attributes that can be applied to the class and
52         methods, and stores them into TypeStubInfo and MethodStubInfo.
53
54         Also, serializers for input and output types are created and
55         stored into the MethodStubInfo.
56
57         There is a cache managed by TypeStubManager (it has to be
58         threadsafe, as SoapHttpClientProtocol will call this and will
59         require thread safe semantics). 
60
61         The cache tracks types, and types track their methods.  This
62         information needs to be computed ahead of time, due to the
63         possible name-clash resolution that VisualStudio uses. 
64
65 * Current shortcomings and problems.
66
67         * Need a cache that maps (type, method-name) to the
68           precomputed MethodMetadata.  The type has to be a derived
69           class from SoapHttpClientProtocol.
70
71         * We do not support SoapExtensions.
72
73         * We do not support extracting the parameter information and
74           pass the result attribute names to the XmlSerializer, as specified in
75           `Customizing SOAP Messages/Customizing the SOAP Message with XML Serialization'
76
77         * We do not pass the SoapClientMessage as we should to any
78           extensions
79
80         * Ignored elements in the MethodStubInfo:
81                 * ParameterStyle, have to understand what this does.
82                 * Binding
83                 * RoutingStyle.
84
85 * Other notes.
86
87           VisualStudio does not allow method overloaded in web
88           services, it requires that:
89
90                 [WebMethod (MethodName="AlternateName")]
91                 public int Name ()
92
93           I tried this:
94
95                 [WebMethod] public string A () {}
96                 [WebMethod] public string A (int b) {}
97
98           Had to change it to:
99         
100                 [WebMethod] public string A () {}
101                 [WebMethod (MethodName="B")] public string A (int b) {}
102
103           The generated stubs though for "Invoke" does not use the
104           actual name of the web method in the call to "Invoke", it
105           uses a sequential number:
106
107                 [System.Web.Services.WebMethodAttribute(MessageName="A1")]
108                 [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/B", RequestElementName="B", RequestNamespace="http://tempuri.org/", ResponseElementName="BResponse", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
109                 [return: System.Xml.Serialization.XmlElementAttribute("BResult")]
110                 public string A(int a) {
111                     object[] results = this.Invoke("A1", new object[] {
112                                 a});
113                     return ((string)(results[0]));
114                 }
115         
116                 /// <remarks/>
117                 public System.IAsyncResult BeginA1(int a, System.AsyncCallback callback, object asyncState) {
118                     return this.BeginInvoke("A1", new object[] {
119                                 a}, callback, asyncState);
120                 }
121         
122                 /// <remarks/>
123                 public string EndA1(System.IAsyncResult asyncResult) {
124                     object[] results = this.EndInvoke(asyncResult);
125                     return ((string)(results[0]));
126                 }
127
128
129         The above is interesting, because it means that the method to
130         invoke on the target should be pulled from
131         `RequestElementName', if the value is not found, then we use
132         the name of the method provided.