Pregunta

Soy un novato en WCF, actualmente estoy desarrollando un servicio TCP WCF y no estoy seguro de entender los parámetros de paso correctamente o no, así que le recomiendo que comente y dé una forma estandarizada.

Para aclarar las cosas, desarrollé un pequeño servicio para fines de prueba que tiene un solo método y depende de una dll .Net externa que expone a una sola clase. El código de contrato de servicio

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

Donde actionType , CalculateType , action son enumeraciones declaradas dentro del dll externo y DataSeries es una clase declarada dentro de la dll.

La definición original para la clase DataSeries en la dll está marcada por [Serializable] y no [DataMember] en sus miembros.

Estoy usando la tercera dll en el lado del cliente y del servidor, mi sorpresa fue que ambas aplicaciones funcionaron bien sin poner [DataContract] en la clase DataSeries y sin usar ninguna de [EnumMember] dentro de enumeraciones, [DataMember] dentro de la clase.

Entonces, ¿qué está pasando?

Otro experimento:

Eliminar a la tercera parte del lado del cliente y usar el servicio tal como está ¿Encontré que el vs2008 genera los enums y la clase DataSeries y los marca con los atributos apropiados? como

    [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,
    }
¿Fue útil?

Solución

DataContract , DataMember y EnumMember son utilizados por los atributos DataContractSerializer (generalmente basicHttpBinding o wsHttpBinding ). Si está exponiendo un punto final con enlace TCP ( netTcpBinding ) solo se requiere SerializableAttribute . Tenga en cuenta que con DataContractSerializer solo podría agregar SerializableAttribute a sus clases y se serializarán automáticamente todos los campos.

Le recomendaría lo siguiente: si desea que su servicio sea interoperable, use basicHttpBinding y marque sus clases con los atributos DataContract y DataMember. Si su cliente es una aplicación .NET, use netTcpBinding y marque sus clases con SerializableAttribute.

También puedes leer este publicación para comparar entre diferentes enlaces.

Otros consejos

  

Pero sin usar DataContract o cualquiera   Atributos, encontré el lado del cliente.   trabajando correctamente

Sí, es cierto: si los tipos de datos que usa no están marcados con [DataContract], WCF intentará usar el serializador SOAP predeterminado en ellos y simplemente serializará todo lo que sea público (todas las propiedades públicas).

Funciona, pero puede que no sea lo que usted desea / espera, por lo que me gustaría ser una segunda opinión de la dinastía, simplemente siempre use los atributos explícitos de [DataContract] en sus tipos. Cuanto más claro sea tu intención para ti mismo (u otros programadores que necesiten mantener tu código más adelante), mejor. Estos " trucos de magia " que suceden detrás de escena tienden a causar confusión a veces: es mejor que no confíes demasiado en ellos

Marc

Por lo tanto, para mí uso [DataContract] s, paso un solo parámetro y devuelvo un contrato de datos.

Esto proporciona más flexibilidad, ya que puedo extender el contrato de datos con nuevos atributos opcionales al contrato de datos, sin romper ningún cliente existente.

Enums También creo contactos de datos para; porque luego puedo hacer lo mismo, extender la enumeración sin romper nada, y puedo controlar el espacio de nombres.

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

A continuación, debe marcar el contrato de servicio con

[ServiceKnownType(typeof(GenderEnum))]
public interface IServiceContract
{
    ....
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top