简体   繁体   中英

How does Visual Studio's “Add Service Reference” deserialize objects?

How does Visual Studio 2013 deserialize objects when you use Add Service Reference on a project? I ask because I have the following class:

    public class RTMImagePackage
    {
        private int maxImages = 15;

        [DataMember(EmitDefaultValue = false)]
        public int MaxImages
        {
            get { return this.maxImages; }
            private set { this.maxImages = value; }
        }

        [OnDeserialized]
        void OnDeserialized(StreamingContext c)
        {
            if (maxImages == 0)
            {
                maxImages = 15;
            }
        }
    }

If I self-host using local IIS and then create a separate project and add this WCF service using Add Service Reference , any new instance of RTMImagePackage always has a MaxImages value of 0, even though I set it to 15 in multiple places, even inside a method prefaced with OnDeserialized .

If I throw in some breakpoints, I can see that the OnDeserialized method is never even called on the web service side, even if I try to update the service reference with the breakpoint in place.

Basically I am trying to guarantee that the client-side will always have MaxImages set to 15 when it generates the proxy class WITHOUT having to use partial classes. Is there a clear way to do this? I've checked other answers and their approach was to use OnDeserialized or OnDeserializing but that doesn't seem to be working for me.

Any tips?

Visual Studio has no way of probing information about your underlying .NET classes using the Add Service Reference wizard 1 . All it has to go on is the WSDL that your WCF service generates, and that WSDL is not going to have any way of saying that one of the data members one of your service's concrete classes has a backing field with an initial value of 15.

Also, your client has no way of knowing that your class' OnDeserialized method sets that backing field to 15 if it is currently 0 during deserialization. OnDeserialized is a method that runs when the service recieves data from the client. The OnDeserialized method's behavior is not exposed as part of your service's interface.

From what I can ascertain, I don't see any way of indicating a custom default value in the WCF interface, and all the advice I can find on using custom default values recommend the OnDeserialized approach that you are already using.

However, it appears that if you use ChannelFactories rather than the proxies that Add Service Reference generates, your client application can use .NET definitions for your service data objects and these can be shared between your service and your client. In other words, your client can instantiate instances of RTMImagePackage that are defined in a shared assembly, rather than use service proxy classes. This should allow you to do things like including default values and other things that could not be ascertained purely from the WSDL.

More information on ChannelFactories can be found here: http://www.codeproject.com/Tips/558163/Difference-between-Proxy-and-Channel-Factory-in-WC


1 In fact, your service's interface shouldn't be defined in a class in the first place. It should be defined in an interface .

I'm not sure how the OnDeserialized method is intended to be triggered, so I won't speak to that.

Basic serialization requires public get and set accessors. You've got a public get , but your set is private. Set both of these to public and your object should serialize correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM