WCF, Interface de type de retour et KnownTypes
Je suis de la création d'un service WCF, et je vais avoir beaucoup de mal avec certains Sérialisation des problèmes. Peut-être qu'il y a juste 1 façon de le faire, mais je tiens à le confirmer
Voici mon exemple de code :
Contrats
public interface IAtm
{
[DataMember]
double Latitude { get; set; }
[DataMember]
double Longitude { get; set; }
}
[ServiceContract]
public interface IAtmFinderService
{
[OperationContract]
ICollection<IAtm> GetAtms();
}
Service De La Mise En Œuvre :
[KnownType(typeof(Atm))]
[KnownType(typeof(List<Atm>))]
[ServiceKnownType(typeof(Atm))]
[ServiceKnownType(typeof(List<Atm>))]
public class AtmFinderService : IAtmFinderService
{
public ICollection<IAtm> GetAtms()
{
return new List<IAtm>()
{
new Atm() { Latitude = 1, Longitude = 1 },
new Atm() { Latitude = 2, Longitude = 2 }
};
}
}
J'ai ajouté tous les KnownType et ServiceKnownType attributs parce que je pensais qu'il y avait quelque chose qui manque..
Alors maintenant, j'ai fait quelques tests. J'ai essayé de créer une application de console, à l'aide de la "ajouter une référence de service" méthode pour faire de VS de créer automatiquement le proxy. De cette façon, j'obtiens une fonction comme
object[] GetAtms();
Lorsque j'essaie de l'appeler, j'obtiens cette erreur :
La InnerException message a été 'Type
'WCFTest.Atm avec des données nom du contrat
Atm:http://schemas.datacontract.org/2004/07/WCFTest'
n'est pas prévu. Envisagez d'utiliser un
DataContractResolver ou d'ajouter tous types
pas connu statiquement à la liste des
les types connus - par exemple, en utilisant
le KnownTypeAttribute attribut ou par
en les ajoutant à la liste des types connus
passé à DataContractSerializer.'.
Très agréable... alors, je pense que VS du code généré automatiquement est de la merde. J'ai fait la modification suivante dans mon service (et de toutes les classes associées et mises en œuvre) :
[OperationContract]
ICollection<Atm> GetAtms();
Alors maintenant, je suis de retour d'un type concret. Après la mise à jour de la référence de service, il crée une copie de l'Atm classe, avec ses membres et d'autres choses.
Après l'appel de service, l'appel réussit.
J'ai pensé que c'était un mauvais comportement liés au code généré automatiquement, donc j'ai essayé de créer un très simple d'hôte du client/de l'application. J'ai commencé une console de l'hôte à l'écoute sur un port, puis créé un client qui utilise le ClientBase la classe pour faire un appel au service. Même comportement... si le service est mis en place au retour d'une interface de type, il échoue. Si je change, il renvoie le type de béton, il fonctionne. Je pense que j'ai un problème avec le KnownType attributs, je dois être en manque de quelque chose que le processus ne peut pas traiter. mais je ne sais pas quoi.
Vous devez vous connecter pour publier un commentaire.
Ok, j'ai réussi à le résoudre
Le problème, comme je le vois, est-ce
Depuis que je suis de retour d'une interface et non une classe concrète, WCF ne sait pas à quoi s'attendre sur l'autre extrémité. Donc, il peut être n'importe quoi. Quand il obtient une Liste, il est de la confusion.
La bonne façon de le faire est d'ajouter le KnownType attributs en cas de besoin.
Qui a besoin de savoir ces types? la mise en oeuvre du service, pour sérialiser et désérialiser correctement. Toutefois, le client pourparlers avec l'interface du service, non pas avec la mise en œuvre elle-même. C'est pourquoi l'ajout de theKnownType attribut dans le service de la mise en œuvre n'a pas de travail
Le problème ici est que, les interfaces ne permettent pas de KnownType attributs, mais ils ne permettent ServiceKnownType attributs. La solution à ce problème est d'ajouter le type attendu dans l'interface de service contrat, et voila, tout fonctionne ok et l'utilisation d'interfaces