Ortund
Ortund

Reputation: 8245

Service reference generates soap proxy incompatible with the web service

Per the WSDL that I used to get the reference, the operation I'm trying to use is defined as follows.

For reasons of security, I've replaced the service's name with "MyService" in all references.

<message name="MyService_fetchOperation">
    <part name="user" type="xsd:string"/>
    <part name="passwd" type="xsd:string"/>
    <part name="package" type="xsd:string"/>
    <part name="txType" type="xsd:string"/>
    <part name="swref" type="xsd:string"/>
    <part name="force" type="xsd:string"/>
</message>

I'm building a request in C#:

using (var client = new MyService.MyServiceGatewayClient())
{
    response = await client.fetchOperationAsync(USER, PASS, PACKAGE, "509", "", "0");
}

What this request does or what its for doesn't matter in the context of this question.

The request (from Fiddler) looks like this:

POST https://myservice.gateway.thing HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Host: myservice.gateway.thing
Content-Length: 816
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Header>
        <ActivityId CorrelationId="04a608d9-fbfd-4a4d-b26b-e57098352dff" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">
80000162-0005-fb00-b63f-84710c7967bb</ActivityId>
        <VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo6GoRTTueVZOiE2QS303TwoAAAAA6GBrNOg50ESdf6d7KUk2nMLdj/sn/wxCqk4Df+zV1yQACQAA</VsDebuggerCausalityData>
    </s:Header>
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <fetchOperation xmlns="http://myservice.gateway.thing/v1">
            <user>TEST9876</user>
            <passwd>test4139</passwd><!-- plain text password ftw! -->
            <package>SWITCHON</package>
            <txType>509</txType>
            <swref/>
            <force>0</force>
        </fetchOperation>
    </s:Body>
</s:Envelope>

This request returns an error on the service that it couldn't find the child element 'user'.

I've queried this with the service admin and he says I need to redefine the namespace in the fetchOperation tag and gave the following example:

<v1:fetchOperation xmlns:v1="http://myservice.gateway.thing/v1">
    ...
</v1:fetchOperation>

I have 2 questions:

  1. Why would such a change be necessary? How would this fix the problem of the service not seeing the "missing" element in the request?
  2. Why, if this change is needed, does the addition of the service reference in VS not generate a SOAP proxy that actually works? Is it an inconsistency on the part of the service developers or have I done something wrong?

Upvotes: 0

Views: 800

Answers (1)

Ricardo Pontual
Ricardo Pontual

Reputation: 3757

Another way to generate a proxy client for a service is using svutil.exe, a command line tool to generate service model code from metadata, web or wsdl file.

Microsoft Docs svcutil.exe

It's included with Visual Studio instalation, you can open the Developer Command Prompt and execute it like this:

svcutil http://url/service.svc /Language=c#

You can also install svcutil with Microsoft Windows SDK: https://www.microsoft.com/en-us/download/details.aspx?id=8279

For a real example I've used this service: http://www.chemspider.com/MassSpecAPI.asmx

svcutil http://www.chemspider.com/MassSpecAPI.asmx /Language=c#

It was generated the MassSpecAPI.cs file, below part of the generated proxy classes:

//------------------------------------------------------------------------------
// <auto-generated>
/ ....
// </auto-generated>
//------------------------------------------------------------------------------

[assembly: System.Runtime.Serialization.ContractNamespaceAttribute("http://www.chemspider.com/", ClrNamespace="www.chemspider.com")]

namespace www.chemspider.com
{
    using System.Runtime.Serialization;


    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
    [System.Runtime.Serialization.CollectionDataContractAttribute(Name="ArrayOfString", Namespace="http://www.chemspider.com/", ItemName="string")]
    public class ArrayOfString : System.Collections.Generic.List<string>
    {
    }

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
    [System.Runtime.Serialization.DataContractAttribute(Name="ECompression", Namespace="http://www.chemspider.com/")]
    public enum ECompression : int
    {

        [System.Runtime.Serialization.EnumMemberAttribute()]
        eGzip = 0,
    }

Upvotes: 1

Related Questions