Note that there are some explanatory texts on larger screens.

plurals
  1. POGetting a Windows Client to Change its Web Service Endpoint Dynamically – Problems with a WSDL
    primarykey
    data
    text
    <p>This describes a problem I had and the solution found, which I did not see discussed elsewhere (except the Background material).</p> <h1>Background – What Should Work (but May Not)</h1> <p>Let’s assume a web service defined by <code>“https://mysite.com/?wsdl”</code>, whose functions are to be called by a Windows client “myclient.exe”. In Visual Studio, you provide a “Service Reference” (The problem described here also manifests with the older-style “Web Reference”.)</p> <p>Suppose you have more than 1 machine (mysite and mysite2) exposing the same web services. It is desirable to just change the client’s choice of endpoint at runtime to point to the correct machine, without having to update the Service Reference. This could be done in 3 ways:</p> <ol> <li><p>Edit the deployed myclient.exe.config (or its source at compile time in VS, app.config), in particular:</p> <pre><code>&lt;system.serviceModel&gt; ... &lt;client&gt; &lt;endpoint address="https://mysite2.com/?wsdl" …/&gt; &lt;/client&gt; &lt;/system.serviceModel&gt; </code></pre></li> <li><p>Arrange your client code so that it reads in or selects the endpoint address, and sets it in the constructor (where “MyWebService” is the name of the Service Reference, and MyWebServiceBinding is defined in app.config), e.g. in C#:</p> <pre><code>public static EndpointAddress remoteAddress = new EndpointAddress("https://mysite2.com/?wsdl"); public static BasicHttpBinding basicBinding = new BasicHttpBinding("MyWebServiceBinding"); //Your binding type may differ public MyWebService.myWebServicePortTypeClient mws = new MyWebService.myWebServicePortTypeClient(basicBinding, remoteAddress); </code></pre></li> <li><p>Do like (2), but instead of in the constructor, set the endpoint later, say, during the first call to the service:</p> <pre><code>private void SetMyEndpointAddress(MyWebService.myWebServicePortTypeClient mws) { mws.Endpoint.Address = new System.ServiceModel.EndpointAddress("https://mysite2.com/?wsdl"); } </code></pre></li> </ol> <p>All of these can still quietly fail if the specifics of the service WSDL are problematic (probably not generated in a routine manner by a MS server; PHP NuSoap in my case). Assuming you have control over the server WSDL, the next section explains what to look for.</p> <h1>Removing Unnecessary URLs from the WSDL</h1> <p>The WSDL is a long document with overall structure shown next. If any of the phrases pointed to here by "&lt;===" contains a URL (e.g., <code>https://mysite.com/...</code>), change its generation process so that this is no longer true.</p> <pre><code> &lt;definitions ... xmlns:tns="soap/MyWebServices" &lt;=== ... targetNamespace="soap/MyWebServices"&gt; &lt;=== &lt;types&gt; &lt;xsd:schema elementFormDefault="qualified" targetNamespace="soap/MyWebServices"&gt; &lt;=== ... &lt;/xsd:schema&gt; &lt;/types&gt; [multiple &lt;message&gt;...&lt;/message&gt; sections, ones for each defined function.] &lt;portType name="myWebServicesPortType"&gt;...&lt;/portType&gt; &lt;binding name="MyWebServicesBinding" type="tns:myWebServicesPortType"&gt;...&lt;/binding&gt; &lt;service name="MyWebServices"&gt;...&lt;/service&gt; &lt;/definitions&gt; </code></pre> <p>In addition, within the <code>&lt;binding&gt;…&lt;/binding&gt;</code> section, the “soapAction” for each function should be only the function name. It should not include a URL prefix (followed by “#” and the function). Typical function:</p> <pre><code> &lt;operation name="getMyData"&gt; &lt;soap:operation soapAction="getMyData" &lt;=== style="document"/&gt; &lt;input&gt;&lt;soap:body use="literal" namespace=""/&gt;&lt;/input&gt; &lt;output&gt;&lt;soap:body use="literal" namespace=""/&gt;&lt;/output&gt; &lt;/operation&gt; </code></pre> <p>The ONLY place where a URL to the particular machine should appear is in the <code>&lt;service&gt;</code> section:</p> <pre><code> &lt;service name="MyWebServices"&gt; &lt;port name="MyWebServicesPort" binding="tns:MyWebServicesBinding"&gt; &lt;soap:address location="https://mysite.com/?wsdl"/&gt; &lt;/port&gt; &lt;/service&gt; </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload