WCF Services and Object Constructors

折月煮酒 提交于 2019-12-23 19:08:22

问题


I am just learning WCF services. I have a method that returns an object I created called GPSPosition. A GPS Position object has a Latitude and a Longitude. The object should never really exist without these properties.. So, I want to have the constructor accept the Lat and Long floats. So when the object is created, the values are set, and can never be invalid (Unset).

But, it's an object of my WCF service. Can as WCF service object, that my calling application uses, have a constructor? If I var position = new GpsPosition{ lat=1, lon=1 }; in my calling code, will the constructor work? Can you have constructors in WCF classes?

I thought they are shared among different languages - so if the service is used by Java, for example, I'm unsure how the constructor will fire. The object structure is shared to the calling app, no? Can you fire .net code in the constructor (And getter and setter methods, for that case)?

And if the constructor isn't usable - is there a way to ensure my object is never invalid? (Must have valid lat/long values between -180 and +180)?


回答1:


The answer will depend on which serialization model your type GpsPosition uses. The two most common ones used in WCF are POCO (plain-old CLR object) and [DataContract]. In the former, the object must have a parameter-less constructor, which goes against your requirement (that the values need to be set once). In the latter, the object constructor is not invoked - instead an uninitialized instance of the type is created, and its members are set via deserialization.

So constructors are not an alternative to validate the objects coming from the wire. What you need to validate the object, instead of the constructor, is a serialization callback, which is invoked when the deserialization is complete. The WCF serializer will call them when the deserialization is done, and there you can check whether the object was properly initialized, and throw an exception otherwise. This blog post has more details on serialization callbacks, and the code below shows one possible implementation for your scenario.

[DataContract]
public class GpsPosition
{
    private float _lat;
    private float _lon;
    private bool _latWasSet;
    private bool _lonWasSet;

    public GpsPosition(float lat, float lon)
    {
        _lat = lat;
        _lon = lon;
    }

    [DataMember]
    public float lat
    {
        get { return _lat; }
        private set
        {
            _lat = value;
            _latWasSet = true;
        }
    }

    [DataMember]
    public float lon
    {
        get { return _lon; }
        private set
        {
            _lon = value;
            _lonWasSet = true;
        }
    }

    [OnDeserialized]
    void OnDeserialized(StreamingContext ctx)
    {
        if (!_latWasSet || _!lonWasSet ||
            _lat < -90 || _lat > 90 ||
            _lon < -180 || _lon > 180)
        {
            throw new InvalidOperationException("Required property is missing");
        }
    }
}


来源:https://stackoverflow.com/questions/15571902/wcf-services-and-object-constructors

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!