| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- Notes on the Soap Client
- ------------------------
- * Preparing an invocation.
- To send a SOAP request to a remote server, applications will
- instantiate a class created by the WSDL compiler that derives
- from SoapHttpClientProtocol.
- The classes generated are fairly simple, they contain stubs
- for all of the methods generated just pass the name of the
- method and the arguments they receive to the protected
- Invoke() method on SoapHttpClientProtocol.
- To invoke a method on a SOAP server it is necessary to
- instantiate the generated class, and possibly configure the
- Url property of it (to point to the right server) and then
- invoking the stubs.
- SoapHttpClientProtocol will create a SoapClientMessage based
- on this information. The SoapClientMessage class is used to
- pass the information to hooks or extensions in the .NET
- Framework. These hooks are invoked at various phases to
- customize the SOAP message.
- For the first pass of our implementation, we will not invoke
- any of those hooks. They are required for things like WSS,
- but we do not need this now.
- A WebRequest object of type POST is created, and we will use
- this to send our Soap message.
- * Creating the SOAP request
- The SOAP request is fairly simple; For our initial
- implementation we will only support the schema encoding.
- For each stub method, we need to create an XmlSerializer for
- the parameter values, and another one for the return value.
- The encoding is fairly simple, see the post on
- mono-serialization-list for a sample program.
- * Processing the return value.
- Soon.
- * Metadata
- Methods.cs extracts class and method information: it basically
- pulls all the attributes that can be applied to the class and
- methods, and stores them into TypeStubInfo and MethodStubInfo.
- Also, serializers for input and output types are created and
- stored into the MethodStubInfo.
- There is a cache managed by TypeStubManager (it has to be
- threadsafe, as SoapHttpClientProtocol will call this and will
- require thread safe semantics).
- The cache tracks types, and types track their methods. This
- information needs to be computed ahead of time, due to the
- possible name-clash resolution that VisualStudio uses.
- * Current shortcomings and problems.
- * Need a cache that maps (type, method-name) to the
- precomputed MethodMetadata. The type has to be a derived
- class from SoapHttpClientProtocol.
- * We do not support SoapExtensions.
- * We do not support extracting the parameter information and
- pass the result attribute names to the XmlSerializer, as specified in
- `Customizing SOAP Messages/Customizing the SOAP Message with XML Serialization'
- * We do not pass the SoapClientMessage as we should to any
- extensions
- * Ignored elements in the MethodStubInfo:
- * ParameterStyle, have to understand what this does.
- * Binding
- * RoutingStyle.
- * Other notes.
- VisualStudio does not allow method overloaded in web
- services, it requires that:
- [WebMethod (MethodName="AlternateName")]
- public int Name ()
- I tried this:
- [WebMethod] public string A () {}
- [WebMethod] public string A (int b) {}
- Had to change it to:
-
- [WebMethod] public string A () {}
- [WebMethod (MethodName="B")] public string A (int b) {}
- The generated stubs though for "Invoke" does not use the
- actual name of the web method in the call to "Invoke", it
- uses a sequential number:
- [System.Web.Services.WebMethodAttribute(MessageName="A1")]
- [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)]
- [return: System.Xml.Serialization.XmlElementAttribute("BResult")]
- public string A(int a) {
- object[] results = this.Invoke("A1", new object[] {
- a});
- return ((string)(results[0]));
- }
-
- /// <remarks/>
- public System.IAsyncResult BeginA1(int a, System.AsyncCallback callback, object asyncState) {
- return this.BeginInvoke("A1", new object[] {
- a}, callback, asyncState);
- }
-
- /// <remarks/>
- public string EndA1(System.IAsyncResult asyncResult) {
- object[] results = this.EndInvoke(asyncResult);
- return ((string)(results[0]));
- }
- The above is interesting, because it means that the method to
- invoke on the target should be pulled from
- `RequestElementName', if the value is not found, then we use
- the name of the method provided.
|