2013-03-22 113 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