NOTES 4.7 KB

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