Pregunta

Tengo un contrato de servicio que define un método con un parámetro de tipo System.Object (xs:anyType en el WSDL).Quiero poder pasar tanto tipos simples como complejos en este parámetro.Los tipos simples funcionan bien, pero cuando intento pasar un tipo complejo definido en mi WSDL, aparece este error:

Elemento 'http://tempuri.org/:valor' contiene datos del 'http://schemas.datacontract.org/2004/07/MyNamespace:MyClass'contrato de datos.El deserializador no tiene conocimiento de ningún tipo que se asigne a este contrato.Agregue el tipo correspondiente a 'MyClass' a la lista de tipos conocidos; por ejemplo, utilizando el atributo KnownTypeAttribute o agregándolo a la lista de tipos conocidos pasados ​​a DataContractSerializer.

Agregarlo como tipo conocido no ayuda porque ya está en mi WSDL.¿Cómo puedo pasar un objeto de tipo complejo mediante un parámetro "xs:anyType"?

Más información:

Creo que esto funciona cuando uso NetDataContract, pero no puedo usarlo porque mi cliente es Silverlight.

He visto referencias a tipos complejos que extienden explícitamente xs:anyType, pero no tengo idea de cómo hacer que WCF genere un WSDL que haga eso, y no tengo idea de si sería útil o no.

Gracias

¿Fue útil?

Solución 3

Resolví este problema utilizando el atributo ServiceKnownType.Simplemente agrego mi tipo complejo como tipo de servicio conocido en mi contrato de servicio y el error desaparece.No estoy seguro de por qué esto no funcionó la última vez que lo probé.

No parece afectar al WSDL de ninguna manera, por lo que sospecho que la secuencia serializada debe tener alguna diferencia que informe al deserializador que el objeto se puede deserializar usando mi tipo.

Otros consejos

NetDataContract funciona porque NetDataContractSerializer incluye información de tipo.

El atributo KnownType indica a DataContractSerializer cómo deserializar el mensaje.Al ser específica de la implementación, esta es información que va más allá de la definida por el contrato público y no pertenece al WSDL.

Nunca podrá pasar ningún tipo de datos antiguo porque el deserializador necesita identificar el tipo apropiado y crear una instancia.

Es posible que pueda derivar sus tipos conocidos en tiempo de ejecución en lugar de tenerlos codificados en el DataContract.Echar un vistazo aquí para una muestra.

Espero que esto ayude.Vi a un colega mío usar este código para enviar tipos de datos complicados y para mí esto es bastante simple.Esto se usó con basicHttpBinding y funciona bastante bien con MOSS BDC, así como con otras aplicaciones que usan el enlace básico.

  1. Crear un contrato de datos basado en una clase genérica
  2. Utilizar el contrato de datos cuando sea necesario enviar la información

    [Contrato de datos(Espacio de nombres = "http://Service.DataContracts", Name =" ServiceDatacontractBase ")] Clase pública ServiceAtAcontract {

    public ServiceDataContract() { }
    
    public ServiceDataContract(TValueType Value)
    {
        this.m_objValue = Value;
    }
    
    private TValueType m_objValue;
    
    [DataMember(IsRequired = true, Name = "Value", Order = 1)]
    public TValueType Value
    {
        get { return m_objValue; }
        set { m_objValue = value; }
    }
    

    }

Utilice este contrato de datos siempre que sea necesario en las funciones WCF que devuelven el tipo de datos complicado.Por ejemplo:

public ServiceDataContract<string[]> GetStrings()
{
    string[] temp = new string[10];
    return new ServiceDataContract<string[]>(temp);
}

Actualizar:ServiceDataContract es una clase genérica que utiliza TValueType.No aparece debido a algún problema con la representación del HTML.

Intente utilizar sustitutos de contrato de datos para asignar objetos no compatibles que sean específicos de dot net o de tipos no interoperables.Ver MSDN

Por ahora, he solucionado este problema creando un nuevo tipo de contrato de datos que puede incluir otro tipo de contrato de datos o un tipo simple.En lugar de pasar el tipo Objeto, ahora paso esta clase contenedora.Esto funciona bien, pero aún así me gustaría saber si existe una solución al problema original.

Intenté agregar el atributo ServiceKnownType, especificando el tipo que estoy intentando pasar, pero sigo recibiendo el mismo error. También intenté agregar el atributo KnownType a mi contrato de datos (lo cual parecía una tontería porque era del mismo tipo que el contrato de datos).Supongo que agregarlos en tiempo de ejecución no ayudará si agregarlos en tiempo de compilación no ayuda.

Si estuviera ampliando otro tipo complejo, me parece que querría agregar el atributo KnownType a ese tipo base.Pero como mi tipo base es Objeto, no veo ninguna forma de hacerlo.

En cuanto a los sustitutos, me parece que se utilizan para tipos de envoltura que no tienen un contrato definido.En mi caso sin embargo sí tengo el contrato definido.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top