2013-03-22 2 views
3

Я просто изучаю службы WCF. У меня есть метод, который возвращает объект, который я создал, называемый GPSPosition. Объект позиции GPS имеет широту и долготу. Объект никогда не должен существовать без этих свойств. Итак, я хочу, чтобы конструктор принимал поплавки Lat и Long. Поэтому, когда объект создается, значения устанавливаются и никогда не могут быть недопустимыми (Unset).WCF Services and Object Constructors

Но, это объект моей службы WCF. Может ли объект службы WCF, используемый моим вызывающим приложением, иметь конструктор? Если I var position = new GpsPosition{ lat=1, lon=1 }; в моем кодовом коде, будет ли работать конструктор? Можете ли вы иметь конструкторы в классах WCF?

Я думал, что они разделены между разными языками - поэтому, если служба используется Java, например, я не знаю, как будет работать конструктор. Объект Структура является общим для вызывающего приложения, нет? Можете ли вы запустить код .net в конструкторе (и методы getter и setter, для этого случая)?

И если конструктор не используется - существует ли способ обеспечить, чтобы мой объект никогда не был недействительным? (Должны иметь действительные значения lat/long между -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 Я верю из всех людей, с которыми я столкнулся сегодня. Только вы можете ответить на него. – Arbaaz