wcf - servicio - los metadatos contienen una referencia que no se puede resolver
WCF: configuración de tipos conocidos (3)
Creo que encontré la respuesta ahora.
El archivo de configuración que publiqué arriba se ve así:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="Person, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral,PublicKeyToken=null">
<knownType type="Employee, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral, PublicKeyToken=null" />
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
<system.serviceModel>
.......
</system.serviceModel>
</configuration>
Lo que acabo de agregar fue el espacio de nombres de la clase Person y la clase Employee . Y no es necesario tener valores de versión y cultura más largos ... La configuración correcta debería ser:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="WCFWithNoLibrary.Person, WCFWithNoLibrary">
<knownType type="WCFWithNoLibrary.Employee, WCFWithNoLibrary" />
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
<system.serviceModel>
.......
</system.serviceModel>
</configuration>
Ahora es más corto y tiene más sentido. Pero si se utilizan bibliotecas de terceros, entonces se requerirá agregar la versión, cultura, publickeytokens.
Quiero saber cómo configurar tipos conocidos en WCF. Por ejemplo, tengo una clase Person y una clase Employee . La clase Empleado es una subclase de la clase Persona . Ambas clases están marcadas con un atributo [DataContract]
.
No quiero codificar el tipo conocido de una clase, como poner un [ServiceKnownType(typeof(Employee))]
en la clase Person para que WCF sepa que Employee es una subclase de Person.
Ahora, agregué a App.config del host la siguiente configuración XML:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="Person, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral,PublicKeyToken=null">
<knownType type="Employee, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral, PublicKeyToken=null" />
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
<system.serviceModel>
.......
</system.serviceModel>
</configuration>
Lo compilé, ejecuté el host, agregué una referencia de servicio en el cliente y agregué un código y ejecuté el cliente. Pero se produjo un error:
El formateador arrojó una excepción al intentar deserializar el mensaje: Hubo un error al intentar deserializar el parámetro
http://www.herbertsabanal.net:person
. El mensaje InnerException fue ''Error en la línea 1, posición 247. Elemento''http://www.herbertsabanal.net:person''
contiene datos del contrato de datos''http://www.herbertsabanal.net/Data:Employee''
. El deserializador no tiene conocimiento de ningún tipo que se corresponda con este contrato. Agregue el tipo correspondiente a ''Empleado'' a la lista de tipos conocidos; por ejemplo, utilizando el atributo KnownTypeAttribute o agregándolo a la lista de tipos conocidos pasados a DataContractSerializer. ''. Por favor, consulte InnerException para más detalles.
A continuación están los contratos de datos:
[DataContract(Namespace="http://www.herbertsabanal.net/Data", Name="Person")]
class Person
{
string _name;
int _age;
[DataMember(Name="Name", Order=0)]
public string Name
{
get { return _name; }
set { _name = value; }
}
[DataMember(Name="Age", Order=1)]
public int Age
{
get { return _age; }
set { _age = value; }
}
}
[DataContract(Namespace="http://www.herbertsabanal.net/Data", Name="Employee")]
class Employee : Person
{
string _id;
[DataMember]
public string ID
{
get { return _id; }
set { _id = value; }
}
}
Por cierto, no usé bibliotecas de clases (bibliotecas de clases WCF o bibliotecas de clases que no sean WCF) para mi servicio. Simplemente lo codifiqué en el proyecto de host.
Supongo que debe haber un problema en el archivo de configuración (consulte el archivo de configuración más arriba). O debo estar perdiendo algo. Cualquier ayuda sería muy apreciada.
Sé que esto fue respondido hace mucho tiempo, pero, otra solución (quizás más obvia para los futuros programadores):
[KnownType(typeof(SubClass))]
public class BaseClass
Scott
Recibí este extenso mensaje de error también en otro caso. Utilicé KnownTypeAttribute
y había implementado con éxito una aplicación que utiliza WCF.RIA
para producción. En la segunda versión, agregué un nuevo subtipo y agregué el correspondiente KnownTypeAttribute
correspondiente (el compilador no lo aceptó sin este atributo, excelente). Sin embargo, lo que el compilador aceptó y lo que se ejecutó en mi máquina no se ejecutó en producción. Solo en producción obtuve el error mencionado anteriormente. Al comparar todos los usos de los subtipos existentes y el nuevo revelé que había olvidado que WCF.RIA
requiere el nombre del subtipo que se utilizará en el nombre de un método, como GetMySubTypes. Entonces, si obtiene este error después de haber agregado los atributos, vea si se debe a las convenciones de WCF.RIA
.