Каков стандартизированный способ передачи сложных типов в WCF?

StackOverflow https://stackoverflow.com/questions/814728

  •  03-07-2019
  •  | 
  •  

Вопрос

Я новичок в 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] внутри класса.

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

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

Удаление третьей стороны со стороны клиента и использование сервиса как есть Я обнаружил, что 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,
    }
Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

Марк

Поэтому для меня я использую [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
{
    ....
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top