Как десериализовать реализацию другого интерфейса с помощью wcf - PullRequest
4 голосов
/ 18 февраля 2011

Следующая ситуация:

Наше программное обеспечение работает с бизнес-объектами, в данный момент они отправляются с wcf с сервера на клиент.

[Serializable]
public class SomeValueBO
{
   public DateTime Timestamp{ get; set; }
}

Они упакованы в сообщениях запроса / ответа.

[DataContract]
public class Response
{
  [DataMember]
  public List<SomeValueBO> Values { get; set; }
}

Проблема:

Мы хотели бы отправить DTO клиенту вместо бизнес-объекта. Я слышал, что на клиенте можно получить экземпляр другого типа, чем тот, который был отправлен на сервер.

Пример:

public interface ISomeValue
{
   DateTime Timestamp { get; set; }
}

[Serializable]
public class SomeValueBO : ISomeValue
{
   public DateTime Timestamp { get; set; }
}

[DataContract]
public class SomeValueDTO : ISomeValue
{
   [DataMember]
   public DateTime Timestamp { get; set; }
}

Ответ будет выглядеть так:

[DataContract]
public class Response
{
   [DataMember]
   public List<ISomeValue> Values { get; set; }
}

На сервере:

public class ServiceClass : IService
{
   public Response HandleRequest(Request request)
   {
      Response response = new Response();
      response.Values.Add(new SomeValueBO());

      return response;
   }
}

На клиенте:

Response response = serviceProxy.HandleRequest(request);
ISomeValue value = response.Values[0];

value is SomeValueDTO

Я попытался сделать это с объявлением только известного типа объекта DTO и с эквивалентностью контракта данных, но WCF все еще продолжает десериализовать элемент как экземпляр BO.

Я должен добавить, что оба способа должны работать: отправка BO и получение его как BO, отправка BO и получение DTO, но, конечно, с разными запросами.

Итак, мой вопрос, возможно ли это, и если да, что я делаю не так?

Спасибо за помощь, Enyra

Edit: Я также узнал, что мы используем NetDataSerializer, может ли это быть проблемой, что он не работает?

Ответы [ 2 ]

4 голосов
/ 18 февраля 2011

Даже если вы не использовали NetDataContractSerializer (комментарий), тот факт, что SomeValueBO не объявлен как контракт данных, означает, что он в основном будет действовать как полевой сериализатор , Что является болью , в частности , потому что автоматически реализуемые свойства являются сериализаторами королевской боли - они становятся безумно хрупкими.

Я бы объявил в качестве контракта:

[DataContract]
public class SomeValueBO
{
   [DataMember]
   public DateTime Timestamp{ get; set; }
}

и переключитесь на DataContractSerializer, но учтите, что это является серьезным изменением - вам придется обновлять все клиенты и серверы одновременно. После этого вы сможете иметь альтернативные реализации, если они имеют общую подпись контракта.

Относительно текущего использования NetDataContractSerializer - если это для производительности, есть альтернативы - существуют двоичные сериализаторы на основе контракт , которые быстрее (ЦП) и меньше (пропускная способность), чем NetDataContractSerializer: Тесты производительности сериализаций, используемых привязками WCF

2 голосов
/ 18 февраля 2011

С MSDN :

NetDataContractSerializer отличается от DataContractSerializer одним важным способом: NetDataContractSerializer включает информацию о типе CLR в сериализованном XML, тогда как DataContractSerializer - нет.Поэтому NetDataContractSerializer можно использовать только в том случае, если оба конца сериализации и десериализации имеют одинаковые типы CLR.

Именно поэтому он не работает в настоящее время.

Если вы используете DataContractSerializer вместо этого клиент и служба должны согласовать только сериализованное XML-представление состояния объекта, а не точный тип среды CLR.Вам нужно будет приписать типы обеих сторон с помощью DataContractAttribute, чтобы пространство имен XML, связанное с сериализованным представлением, было одинаковым с обеих сторон.И, очевидно, контракты на данные должны быть эквивалентны с точки зрения сериализованной структуры.

Тем не менее, то, что вы пытаетесь сделать, должно быть работоспособным с DataContractSerializer.Что касается того, является ли это лучшим способом - как и все дизайнерские решения "это зависит".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...