How to prevent 'Specified' properties being generated in WCF clients?
Asked Answered
B

5

10

I have two .NET 3.5 WCF services build with VS2008.

I have two WCF clients in Silverlight to consume these services. The clients are generated with the 'Add Service Reference'. I am using Silverlight 4.

ONE of the proxies is generated with Specified properties for each property. This is a 'message-in' class for my service method :

    // properties are generated for each of these fields
    private long customerProfileIdField;        
    private bool customerProfileIdFieldSpecified;        
    private bool testEnvField;        
    private bool testEnvFieldSpecified;

Now my other service (still with a Silverlight client) does NOT generate Specified properties.

Now I don't care about 'tenets of good SOA'. I just want to get rid of these damn properties because in the context of what I'm doing I absolutely hate them.

There has to be some difference between the two services - but I don't want to have to completely rip them apart to find out the difference.

A similar question before had the answer 'you cant do it' - which is definitely not true because I have it - I just don't know what I did differently.

Edit: I am now in a situation where I regenerate my Silverlight 4 proxy to my 3.5 WCF service (all on the same localhost machine) that sometimes I get 'Specified' properties and sometimes I don't. I no longer think (as I suspected originally) that this is due solely to some endpoint configuration or service level [attribute]. Theres certain triggers in the message itself that cause Specified to be generated (or not). There may be many factors involved or it may be something very simple.

Birr answered 12/1, 2010 at 2:0 Comment(2)
i actually have 3 services that are not creating Specified properties. Only the the fourth does!Birr
Add [XMLSerializerFormat] to attributes on your service: Check to this answerMariko
A
12

try this in your WCF service where the property is declared

[DataMember(IsRequired=true)]
public bool testEnvField { get; set; }

IsRequired=true will negate the need for the testEnvFieldSpecified property

Ailbert answered 12/1, 2010 at 6:41 Comment(5)
what about doing this globally? now my service that was creating Specified properties has just magically stopped creating them. i just added a second OperationContract with a very similar message - so I'm still stuck knowing what is triggering this global behaviorBirr
The only reason i could see why 2 proxies would generate with SpecifiedField and not, is since .n3.5 client applications don't need the "IsRequired" property, they assume it true by default, where as .net2.0 apps need the attribute, they read the wsdl differently. Are both applications SL4?Ailbert
@neil its the same single application! i've now come to a point where after recompiling my 3.5 app and regenerating a proxy for my SL4 client that I will sometimes get 'specified' and sometimes won't. its getting really frustrating! something in the datamodel is causing this behaviorBirr
when using sl4, dont add the reference in visual studio, goto Program Files/Microsoft SDKs/Silverlight 4... there you'll find slsvcutil, use that to generate the proxy, you can customize it much more accurately and get the same type of behaviour everytimeAilbert
slsvcutil MyServer:8081/MyWCFService /out:Proxy.cs /enableDataBinding /n:*,"MyNamespace.Proxy" /ct:System.Collections.ObjectModel.ObservableCollection`1 /r:"%PROGRAMFILES%\Reference Assemblies\Microsoft\Framework\Silverlight\v3.0\System.Windows.dll" Try thatAilbert
D
3

These extra Specified properties are generated for value types which are being specified as optional in either the contract or the attribute markup.

As value types have a value by default, the extra Specified flags are being added for these properties, to allow the client (and server) to distinguish between something explicitly not specified or explicitly specified - which may well be set to the default value. Without it, integers would always end up being 0 (and being serialized) even if you don't set them (because of the mapping to int) in your client code. So when you do, you need to also make sure that you set the Specified flag to true, otherwise these properties will not get serialized.

So to prevent these flags being generated for value types, you would have to change the contract to make these value type properties mandatory, instead of optional.

Hope that makes sense.

Daberath answered 21/1, 2010 at 23:39 Comment(4)
Right that makes perfect sense EXCEPT I don't always get them generated even for value types. Currently all my (even non-nullable) booleans and 'ints' are NOT generating these properties, but occasionally i change something unintentionally in the contract which causes them to be generated (and I am definitely not accidentally adding [DataMember(IsRequired=true)]). I really would like to know how to permanently disable them so they behave like 'normal' objects.Birr
The non-nullable ones should be fine, it's the optional value types only, that will have this.Daberath
its the other way around. its the non-nullable fields that need the specified properties because otherwise you wouldnt know if the default value (false or 0) is what the user actually wanted. the optional ones just wont exist, but the fact that they are optional says thats ok. in either case ALL my properties end up getting Specified properties which basically completely screws all my code. there has to be a set of rules that determines when they are generated and when they arent. its not as simple as the nullability unfortunatley (or fortunately depending upon how you look at it)Birr
Non-nullable for value types is OK. Now, if your boolean would be nullable, THEN you would not know the difference whether the integer's default value of 0 was intended or not. Hence the introduction of the Specified flag. Having said that, it's more about them being required/mandatory than it is about nullability.Daberath
B
0

OK I've found one thing so far that will cause Specified properties to be generated:

  • The presence of an XTypedElement in the message.

These are used by Linq2XSD. I was returning an element from a Linq2XSD model.

This triggered Specified properties to be generated EVERYTHING in all my classes :

    public XTypedElement Foo { get; set; }

This however didn't :

    public XElement Foo { get; set; }

Still curious as to why this is, and if there are any other things that trigger this.

Birr answered 15/1, 2010 at 5:3 Comment(1)
I'm suddenly getting a similar issue in a web service that used to function as written, although I'm not using XTypedElement or Linq2XSD, and I'm using .NET 4.0Biathlon
L
0

NOTE: I realize this is an old question. I'm adding this here because this question comes up as a top result on Google, and it's helpful information for whoever comes looking.

Try adding this line into your operation contract declaration:
[XmlSerializerFormat]

It should look something like this:

namespace WebServiceContract
{
    [ServiceContract(Namespace = "http://namespace")]
    [XmlSerializerFormat] //This line here will cause it to serialize the "optional" parameters correctly, and not generate the extra
    interface InterfaceName
    {
        /*...Your web service stuff here...*/
    }
}
Loginov answered 3/12, 2013 at 17:11 Comment(1)
Note that this completely changes the XML serialization engine used for the web service. (Changing from DataContractSerializer to XmlSerializer). The different engine uses a different set of attributes for controlling the serializer output, has different compatibility limits, and different performance characteristics. It's not a minor change.Synapsis
O
0

I found that if I put a DataTable in a service DataContract then the generated client will use xml serializer and thus generate the *IsSpecified members.

Optimize answered 20/4, 2020 at 17:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.