2013-03-22 112 views
3

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

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

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

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

回答

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

请问您可以看看这个吗? http://stackoverflow.com/questions/33752947/unable-to-initialize-member-through-constructor-in-wcf 我相信所有人,我今天遇到SO。只有你可以回答。 – Arbaaz 2015-11-17 10:09:23