Каков стандартизированный способ передачи сложных типов в WCF? - PullRequest
0 голосов
/ 02 мая 2009

Я новичок в WCF, в настоящее время я разрабатываю службу TCP WCF, и я не уверен, правильно ли я понимаю параметры передачи или нет, поэтому я рекомендую вам комментировать и давать стандартизированный способ.

Чтобы прояснить ситуацию, я разработал небольшой сервис для тестирования, который имеет один метод и зависит от внешней .Net dll, которая предоставляет один класс. Код договора на обслуживание

    [ServiceContract]
    public  interface IMyService
    {
        [OperationContract]
        int Test1(actionType at, calculationType ct, action a);
        [OperationContract]
        int Test2(DataSeries s);
    }

Где actionType, calculationType, action - перечисления, объявленные во внешней dll и DataSeries - это класс, объявленный внутри dll.

Оригинальное определение для класса DataSeries в dll отмечено только [Serializable] и [DataMember] на его членах отсутствует.

Я использую 3-й dll на стороне клиента и сервера, и меня удивило, что оба приложения работали нормально, без добавления [DataContract] в класс DataSeries и без использования любого из [EnumMember] внутри перечислений, [DataMember] внутри класса. 1020 *

Так что же происходит?

Еще один эксперимент:

Удаление стороннего поставщика со стороны клиента и использование сервиса как есть Я обнаружил, что vs2008 генерирует перечисления и класс DataSeries и маркирует их соответствующими атрибутами? как

    [System.CodeDom.Compiler.GeneratedCodeAttribute      ("System.Runtime.Serialization", "3.0.0.0")]
    [System.Runtime.Serialization.DataContractAttribute(Name="actionType",  Namespace="http://schemas.datacontract.org/2004/07/DBInterface")]
    public enum actionType : int {

        [System.Runtime.Serialization.EnumMemberAttribute()]
        All = 0,

        [System.Runtime.Serialization.EnumMemberAttribute()]
        Buy = 1,

        [System.Runtime.Serialization.EnumMemberAttribute()]
        Sell = 2,
    }

Ответы [ 3 ]

1 голос
/ 02 мая 2009

DataContract , DataMember и EnumMember используются атрибутами DataContractSerializer (обычно basicHttpBinding или WsHttpBinding ). Если вы предоставляете конечную точку с привязкой TCP ( netTcpBinding ), требуется только SerializableAttribute . Обратите внимание, что с DataContractSerializer вы можете добавить только SerializableAttribute к своим классам, и он автоматически сериализует все поля.

Я бы порекомендовал вам следующее: если вы хотите, чтобы ваш сервис был совместимым, используйте basicHttpBinding и пометьте ваши классы атрибутами DataContract и DataMember. Если ваш клиент является приложением .NET, используйте netTcpBinding и пометьте ваши классы с помощью SerializableAttribute.

Вы также можете прочитать этот пост для сравнения различных привязок.

1 голос
/ 02 мая 2009

Но без использования DataContract или каких-либо атрибуты, я нашел на стороне клиента работает правильно

Да, это правда - если используемые вами типы данных не помечены [DataContract], WCF попытается использовать для них сериализатор SOAP по умолчанию и просто сериализует все, что является общедоступным (все общедоступные свойства).

Это работает - но это может быть не то, что вы хотите / ожидаете - поэтому я бы высказал мнение Дарина - просто всегда используйте явные атрибуты [DataContract] для ваших типов. Чем яснее вы делаете свои намерения перед собой (или другими программистами, которым необходимо поддерживать ваш код позже), тем лучше. Эти «магические трюки», которые происходят за кулисами, порой вызывают путаницу - вам лучше не полагаться на них слишком сильно

Марк

0 голосов
/ 02 мая 2009

Так что для меня я использую [DataContract] s, передаю один параметр и возвращаю контракт данных обратно.

Это дает больше гибкости, поскольку я могу расширить контракт данных с помощью новых дополнительных атрибутов для контракта данных, не нарушая существующих клиентов.

Перечисления, для которых я также создаю Контакты данных; потому что тогда я могу сделать то же самое, расширяя перечисление, ничего не нарушая, и я могу контролировать пространство имен.

[DataContract(Namespace = "http://namespace.mydomain.com/2009/05", Name = "ReferenceTypeData")]
public enum GenderEnum
{
    [EnumMember()]
    Unknown = 0,
    [EnumMember()]
    Male = 1,
    [EnumMember()]
    Female = 2
}

Затем вы должны пометить договор на обслуживание с

[ServiceKnownType(typeof(GenderEnum))]
public interface IServiceContract
{
    ....
}
...