WCF服务和对象构造函数

Cra*_*aig 3 c# wcf serialization

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

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

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

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

car*_*ira 6

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

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

[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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)