WCF服务和对象构造函数

时间:2013-03-22 13:45:18

标签: c# wcf serialization

我只是在学习WCF服务。我有一个方法返回我创建的名为GPSPosition的对象。 GPS位置对象具有纬度和经度。没有这些属性,对象永远不应该存在。所以,我想让构造函数接受Lat和Long浮点数。因此,在创建对象时,将设置值,并且永远不会无效(取消设置)。

但是,它是我的WCF服务的一个对象。可以作为我的调用应用程序使用的WCF服务对象有一个构造函数吗?如果我在调用代码中var position = new GpsPosition{ lat=1, lon=1 };,构造函数是否可以工作?你能在WCF类中拥有构造函数吗?

我认为它们是在不同语言之间共享的 - 所以如果Java使用该服务,例如,我不确定构造函数将如何触发。对象结构与调用应用共享,不是吗?你可以在构造函数中启动.net代码(对于那种情况,还有getter和setter方法)?

如果构造函数不可用 - 有没有办法确保我的对象永远无效? (必须在-180和+180之间有有效的纬度/经度值?)

1 个答案:

答案 0 :(得分:6)

答案取决于您的类型GpsPosition使用的序列化模型。 WCF中使用的两个最常见的是POCO(普通旧CLR对象)和[DataContract]。在前者中,对象必须具有无参数构造函数,这违背了您的要求(值需要设置一次)。在后者中,不调用对象构造函数 - 而是创建该类型的未初始化实例,并通过反序列化设置其成员。

因此,构造函数不是验证来自线路的对象的替代方法。验证对象而不是构造函数所需的是序列化回调,在反序列化完成时调用它。反序列化完成后,WCF序列化程序将调用它们,您可以检查对象是否已正确初始化,否则抛出异常。这个blog post提供了有关序列化回调的更多详细信息,下面的代码显示了您的方案的一种可能实现。

[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");
        }
    }
}