WCF/ASMX Interoperability – Removing the Annoying xxxSpecified when Adding a Web Reference to a WCF Service

January 31, 2012

Today I answered a question in the Hebrew MSDN forums about consuming WCF from a .NET 2 client, using the “Add Web Reference” option of Visual Studio.

Just in case you don’t know Hebrew I’ll sum it up for you – when adding a web reference to a WCF service that exposes a method of the following sort:

int UseScalarTypes(int value1, int value2)

The generated method signature in the client app will look like so:

public void UseScalarTypes(
int value1, bool value1Specified,
int value2, bool value2Specified,
out int UseScalarTypesResult, out bool UseScalarTypesResultSpecified)

The question was why this happens and how this can be fixed to look like the service’s method signature.

Before we continue to see why this happens and how to fix it, the short answer is – Yes, you can make it look like the original contract by using message contracts. Continue reading to see how.

Why this happens:

In WCF the WSDL generated for the above method looks like so:

<xs:element name=”UseScalarTypes”>
<xs:element minOccurs=”0″ name=”value1″ type=”xs:int” />
<xs:element minOccurs=”0″ name=”value2″ type=”xs:int” />

Notice the minOccurs? int is a value type which means it doesn’t accept null values, but still WCF marks it as optional. When you use the “Add Service Reference” option of WCF in Visual Studio, the generator ignores that attribute and creates the method declaration in the client side the same way it is declared in the service contract. However, if you use the old “Add Web Reference” option, the generator checks the minOccurs, realizes that the variable is optional, and since this is a value type, it translates the optional into a set of variables: value + xxxSpecified.

By the way, this is how the WSDL is created for the same method declaration when it is used in an ASMX-style web service:

<s:element name=”UseScalarTypes”>
<s:element minOccurs=”1″ maxOccurs=”1″ name=”value1″ type=”s:int” />
<s:element minOccurs=”1″ maxOccurs=”1″ name=”value2″ type=”s:int” />

Note 1: With ASMX web service, the minOccurs/maxOccurs is set properly because the “Add Web Reference” expects that, and therefore we don’t see this behavior with ASMX web service + add web reference.

Note 2: Since WCF ignores the minOccurs, using the “Add Service Reference” to consume that ASMX web service will result in a client-side method with the same signature as declared in the service (without the xxxSpecified).

So now that we know why this happens, let’s see how to fix it.

Step 1: Create a set of message contracts, one for the request and one for the response (if you have one).

Step 2: In the request message contract class, apply the MessageContract attribute and set the IsWrapped parameter to false, like so:

[MessageContract(IsWrapped = false)]
public class UseScalarTypesRequest

Setting the IsWrapped to false will create the XML without a wrapping element, making the properties look like they are actually method parameters.

Step 3: Add each parameter of the method to the class as a property, and apply the MessageBodyMember attribute to it. You can use this step to rename the property to use the naming convention of parameters by using the Name parameter in the attribute. The result should look like so:

[MessageContract(IsWrapped = false)]
public class UseScalarTypesRequest
[MessageBodyMember(Name = “value1”)]
public int Value1 { get; set; }
[MessageBodyMember(Name = “value2”)]
public int Value2 { get; set; }

Step 4: Do the same for the response message contract, this time you just need one property for the return type of the method, for example:

[MessageContract(IsWrapped = false)]
public class UseScalarTypesResponse
public int Result { get; set; }

Step 5: Change the method signature in the contract and service from using parameters to using the message contracts you’ve created, like so:

UseScalarTypesResponse UseScalarTypes(UseScalarTypesRequest parameters)

Of course the immediate step will be to also change the implementation of your code to reflect the parameters being moved to a wrapper object – for convenience, you can leave your existing code in the service as is, change the contract, and then create the new methods which will simply call the older ones, like so:

UseScalarTypesResponse UseScalarTypes(UseScalarTypesRequest parameters)
UseScalarTypesResponse result = new UseScalarTypesResponse();
result.Result = UseScalarTypes(parameters.Value1, parameters.Value2);
return result;

That’s it, update your web reference in the client side, and watch how the method signature in the client side is without the xxxSpecified.

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>



  1. http://www.aardmail.com/September 6, 2013 ב 9:39 am

    Money Mike coined the phrase “Tiger Blood” back in 86 when he discovered and put together that group “masters of ceremony”. And came up with the song “dynamite”, when he just finished watching an episode of “good times”.

  2. zvievylocx@gmail.comOctober 22, 2013 ב 1:09 pm

    neumodisch? egal. ich klammer mich an jedes kleine stück lower boardstein! hell yeah