我只是在学习WCF服务。我有一个返回我创建的名为GPSPosition的对象的方法。GPS定位对象具有纬度和经度。如果没有这些属性,对象就不应该真正存在。因此,我想让构造函数接受Lat和Long浮点数。因此,当对象被创建时,值将被设置,并且永远不会无效(Unset)。
但是,这是我WCF服务的对象。作为我的调用应用程序使用的WCF服务对象,可以有一个构造函数吗?如果我在调用代码中使用var position = new GpsPosition{ lat=1, lon=1 };
,构造函数会工作吗?WCF类中可以有构造函数吗?
我认为它们在不同语言之间是共享的,所以如果服务被Java使用,我不确定构造函数将如何触发。对象结构共享给调用应用程序,不是吗?您能否在构造函数中激发.net代码(以及getter和setter方法,在这种情况下)?
如果构造函数不可用,是否有办法确保我的对象永远不会无效?(必须在-180和+180之间具有有效的lat/long值)?
发布于 2013-03-22 07:18:16
答案将取决于您的类型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");
}
}
}
https://stackoverflow.com/questions/15571902
复制