Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add Service Reference is generating Message Contracts

When I import a given service using "Add service Reference" on Visual Studio 2008 (SP1) all the Request/Response messages are being unnecessarily wrapped into Message Contracts (named as --> "operationName" + "Request"/"Response" + "1" at the end).

The code generator says:

// CODEGEN: Generating message contract since the operation XXX is neither RPC nor 
// document wrapped.

The guys who are generating the wsdl from a Java service say they are specifying DOCUMENT-LITERAL/WRAPPED.

Any help/pointer/clue would be highly appreciated.

Update: this is a sample of my wsdl for one of the operations that look suspicious. Note the mismatch on the message element attribute for the request, compared to the response.

<!- imports namespaces and defines elements -->
<wsdl:types>
  <xsd:schema targetNamespace="http://WHATEVER/" xmlns:xsd_1="http://WHATEVER_1/" xmlns:xsd_2="http://WHATEVER_2/">
      <xsd:import namespace="http://WHATEVER_1/" schemaLocation="WHATEVER_1.xsd"/>
      <xsd:import namespace="http://WHATEVER_2/" schemaLocation="WHATEVER_2.xsd"/>
      <xsd:element name="myOperationResponse" type="xsd_1:MyOperationResponse"/>
      <xsd:element name="myOperation" type="xsd_1:MyOperationRequest"/>
   </xsd:schema>
</wsdl:types>

<!- declares messages - NOTE the mismatch on the request element attribute compared to response -->
<wsdl:message name="myOperationRequest">
   <wsdl:part element="tns:myOperation" name="request"/>
</wsdl:message>
<wsdl:message name="myOperationResponse">
   <wsdl:part element="tns:myOperationResponse" name="response"/>
</wsdl:message>

<!- operations -->
<wsdl:portType name="MyService">
   <wsdl:operation name="myOperation">
      <wsdl:input message="tns:myOperationRequest"/>
      <wsdl:output message="tns:myOperationResponse"/>
      <wsdl:fault message="tns:myOperationFault" name="myOperationFault"/>
      <wsdl:fault message="tns:myOperationFault1" name="myOperationFault1"/>
   </wsdl:operation>
</wsdl:portType>

Update 2: I pulled all the types that I had in my imported namespace (they were in a separate xsd) into the wsdl, as I suspected the import could be triggering the message contract generation. To my surprise it was not the case and having all the types defined in the wsdl did not change anything.

I then (out of desperation) started constructing wsdls from scratch and playing with the maxOccurs attributes of element attributes contained in a sequence attribute I was able to reproduce the undesired message contract generation behavior.

Here's a sample of an element:

<xsd:element name="myElement">
   <xsd:complexType>
      <xsd:sequence>
         <xsd:element minOccurs="0" maxOccurs="1" name="arg1" type="xsd:string"/>
      </xsd:sequence>
   </xsd:complexType>
</xsd:element>

Playing with maxOccurs on elements that are used as messages (all requests and responses basically) the following happens:

  • maxOccurs = "1" does not trigger the wrapping
  • macOcccurs > 1 triggers the wrapping
  • maxOccurs = "unbounded" triggers the wrapping

I was not able to reproduce this on my production wsdl yet because the nesting of the types goes very deep, and it's gonna take me time to inspect it thoroughly. In the meanwhile I am hoping it might ring a bell - any help highly appreciated.

like image 354
JohnIdol Avatar asked Mar 03 '10 22:03

JohnIdol


People also ask

What are message contracts?

A message contract is used to control the structure of a message body and serialization process. It is used to send/access the information in the soap header. By use of a Message Contract we can customize the parameters sent using a SOAP message between the client and the server.

What is Reuse types in referenced assemblies?

It means that, if you control both the server code and client code and define the datacontract classes in a separate assembly (and add a reference to it in the client code), the svcutil will not generate new classes but instead will re-use your already-defined classes that you use for the server.


2 Answers

I had this same issue and this solved it.

I used this:

    <wsdl:message name="Method">
      <wsdl:part name="parameters" element="s0:Method"/>
    </wsdl:message>

    <wsdl:message name="MethodResponse">
      <wsdl:part name="parameters" element="s0:MethodResponse"/>
    </wsdl:message>

Instead of:

    <wsdl:message name="Method">
      <wsdl:part name="request" element="s0:Method"/>
    </wsdl:message>

    <wsdl:message name="MethodResponse">
      <wsdl:part name="response" element="s0:MethodResponse"/>
    </wsdl:message>

I believe someone mentioned it before but I can't upVote their answer yet!

like image 107
Shanwayne Avatar answered Sep 25 '22 01:09

Shanwayne


Here is another item to check:

  1. Right click on your service reference in the Solution Explorer and select 'Configure Service Reference'

  2. Check whether or not 'Always generate message contracts' is checked.

like image 21
Leigh S Avatar answered Sep 23 '22 01:09

Leigh S