[Silverlight] Un bug dans le générateur de proxy de service WCF pour Silverlight ?
Ou comment perdre 1h30 à chercher pour un truc tout bête 
En effet, récemment, j'ai eu besoin d'écrire une petite application Silverlight qui uploadait des images sur un serveur, via un service WCF.
Coté service WCF, j'ai donc écrit une petite classe, qui devait me permettre de faire transiter les données:
[DataContract]
public class FileToUpload
{
[DataMember]
public string FileName { get; set; }
[DataMember]
public Stream StreamOfFile { get; set; }
}
Et dans mon service, j'utilisais ce type, de façon tout ce qu'il y a de simple:
public void UploadFile(FileToUpload file)
Là déjà, je vous entend me dire: "Thomas, faut que tu apprennes à coder: c'est pas bien d'envoyer une Stream, il est conseillé de prendre un objet de plus bas niveau".
Je suis entièrement d'accord c'est pour cela que je répondrais ceci:
- Lorsque j'ai eu besoin de faire ca, il était tard et je commencais à être fatigué
- L'erreur est humaine

- Il est tout à fait possible d'envoyer une Stream, comme cela est expliqué ici: http://msdn.microsoft.com/en-us/library/ms789010.aspx. La grande contrainte est que la méthode d'upload ne doit prendre qu'un seul paramètre de type Stream.
Ce point étant éclaircit, passons à la suite
Une fois le service développé et la référence rajoutée au projet Silverlight, il devient alors possible d'appeler la méthode UploadFile depuis le code behind. Mais avant cela, il est nécessaire de déclarer un objet de type FileToUpload, qui permettra de définir le nom du fichier et le flux à envoyer. Et là, la fatigue aidant, on ne fait pas attention à une chose toute bête:
Pour ceux qui ne voient toujours pas de quoi je veux parler, regarder le type de la propriété StreamOfFile qui a été générée par le générateur de proxy de Visual Studio et le type de la même propriété, que j'ai définit dans la classe FileToUpload: le générateur a convertit le type Stream en tableau de byte (byte[]) !
Bien que cela semble logique (on peut imaginer que le proxy préfère utiliser un tableau de byte plutôt qu'une Stream, objet plus complexe), cela pose quand même un léger souci. En effet, lorsque l'on essaye d'exécuter l'application, on a droit à une belle erreur de ce type:
Les développeurs qui ont déjà touché à Silverlight savent que ce genre de message peut apparaitre pour 2 raisons particulières
- Le service WCF est sur un domaine différent de l'application Silverlight. Du coup, le fichier clientaccesspolicy.xml n'est pas présent sur le serveur => Dans mon cas, le domaine était le même mais, pour être sur, j'avais aussi mis le fichier en question au bon endroit.
- Les paramètres du fichier web.config ne sont pas corrects => En utilisant le template d'élement nommé "Silverlight-enables WCF Service", les paramètres corrects sont positionné par défaut: il n'est pas nécessaire de le modifier.
Pour savoir ce qu'il se passe réellement, il suffit de regarder le contenu de la réponse renvoyée par le serveur (a l'aide du Web Development Helper par exemple):
La classe Stream est en effet une classe abstraite, autrement dit une classe qu'il n'est pas possible d'instancier, ce que le moteur d'exécution essye, à priori, de faire ! De plus, la méthode dont nous disposons coté client prend en paramètre un objet avec des propriétés possédant des types particuliers. Or coté serveur, cette même méthode accepte en paramètre un objet avec des propriétés de type différents. Du coup, il n'arrive pas à trouver la méthode correspondante et remonte ainsi l'erreur 404, indiquant qu'il ne trouve pas ce qu'il cherche.
Pour information, voici le schéma XML correspondant au type FileToUpload, montrant qu'il nécessite bien une propriété StreamOfFile de type Stream:
Ainsi, on peut aisément ce poser les questions suivantes:
- Pourquoi le générateur de proxy pour Silverlight a convertit automatiquement la propriété de type Stream en propriété de type byte[] ?
- Est-ce un comportement voulu ou un bug sachant que, pour une application WindowsForms, l'ajout de la référence ne pose pas de problème (ie: le bon type, à savoir Stream, est utilisé):
Alors dîtes moi, qu'en pensez-vous ? Quels sont vos avis sur le sujet ?
A+
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :