Использование универсального словаря над wcf: что мне нужно искать? - PullRequest
1 голос
/ 20 августа 2009

Предположим, у меня есть служба WCF и метод в контракте

<ServiceContract()> _
Interface IThingService
'...
  <OperationContract()> _
  Function GetThing(thingId As Guid) As Thing
End Interface

где Thing - обычный класс с обычными свойствами, за исключением одного члена:

Public Class Thing
  ' ...
  Public Property Photos() As Dictionary(Of String, Photo) 
  ' ...
End Class

где Фото - это обычный класс с обычными свойствами.

Итак, я углубляюсь в некоторую документацию, такую ​​как эта статья MSDN и эта запись в блоге , и теперь я растерялся, если мне нужно много понять о DataContractSerializer и подробностях о том, как служба сериализует свойство Photos.

Нужно ли идти туда или я могу что-то сделать, чтобы WCF на сервере автоматически взаимодействовал с моим клиентом? Мне кажется, что все детали сериализации должны быть абстрагированы - я просто хочу закончить, в потребительском клиентском приложении, с:

Dim foo as Thing = ThingServiceClient.GetThing(someGuid)
Dim myPhotos as Dictionary(Of String, Photo) = foo.Photos

Что мне нужно сделать в моем определении вещи, чтобы сделать эту работу? Что-нибудь, что мне нужно сделать в другом месте, чтобы заставить это работать? Нужно ли беспокоиться о том, чтобы служба прилипала к DataContractSerializer и не использовала XmlSerializer?

Ответы [ 3 ]

3 голосов
/ 03 ноября 2011

Я чуть не покончил с собой, пытаясь решить эту проблему. В конце я все еще жив и с хорошим и маленьким кодом. Наслаждайтесь этим:)

[DataContract, Serializable]
[KnownType("GetKnownTypes")]
public class Dto
{
    [DataMember]
    public Int PropertyA { get; set; }

    [DataMember]
    public String PropertyB { get; set; }

    [DataMember]
    public Dictionary<string, object> MyDictionary { get; set; }

    private static Type[] GetKnownTypes()
    {
        return _myDictionaryValueTypes ?? new Type[] { Typeof(Dictionary<string, object>) };
    }

    private void MyDictionaryValueTypes()
    {
        if (XmlDictionary == null) return;
        _myDictionaryValueTypes = XmlDictionary.Values.Where(value => value != null).Select(value => value.GetType()).ToArray();
    }
}

Единственное, что вам нужно убедиться, это вызвать MyDictionaryValueTypes и все.

1 голос
/ 20 августа 2009

Я был бы осторожен с раскрытием ваших бизнес-объектов непосредственно в контракте WCF (или веб-службе asmx, или любой другой внешней точке входа в систему). Это интерфейс, который используют ваши внешние системы, и такой интерфейс должен оставаться постоянным, даже если ваши бизнес-объекты меняются внутри. Также могут быть функции для бизнес-объекта, которые имеют смысл на сервере, но не на клиенте.

Кроме того, вам внезапно необходимо изменить бизнес-объекты, чтобы они соответствовали выбранным вами коммуникационным технологиям, например, Вы должны поместить атрибуты в свой бизнес-класс, атрибуты, которые на самом деле не имеют ничего общего с бизнес-классом.

Я бы создал ThingDTO (DTO = объект передачи данных), содержащий данные для передачи клиенту, и инициализировал бы их данными из экземпляра Thing. Это означает, что если вы считаете, что служба WCF является фасадом системы, ThingDTO будет частью вашего фасадного уровня. И поэтому атрибуты для управления сериализацией WCF могут свободно входить сюда.

Тем не менее, это не то же самое, что имеет смысл в вашем случае. Это всего лишь мой общий взгляд на возврат бизнес-классов из интерфейса WCF.

0 голосов
/ 20 августа 2009

Необходимо убедиться, что вы украсили свою «вещь» атрибутом [DataContract], и все ее члены, которые вы хотите включить в контракт данных, должны иметь атрибут [DataMember]. То же самое относится и к вашему классу "Фото".

Пока вам не нужно иметь дело с полиморфизмом (наследованием) и / или пользовательскими коллекциями, так и должно быть. Об остальном должна позаботиться среда выполнения WCF.

Марк

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