Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Thomas Lebrun

Tout sur WPF, LINQ, C# et .NET en général !

[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 Smile

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:

  1. Lorsque j'ai eu besoin de faire ca, il était tard et je commencais à être fatigué
  2. L'erreur est humaine Big Smile
  3. 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 Smile

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:

image

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:

image

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):

image

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:

image

 

Ainsi, on peut aisément ce poser les questions suivantes:

  1. Pourquoi le générateur de proxy pour Silverlight a convertit automatiquement la propriété de type Stream en propriété de type byte[] ?
  2. 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é):

image 

 

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 :
Posted: lundi 1 septembre 2008 10:12 par Thomas LEBRUN
Classé sous : ,

Commentaires

khamlon a dit :

personnellement je dirais bug, pour avoir pas mal bosser sur un service WCF et Silverlight et avoir fait la monté en version de la Beta 1 vers la Beta 2, y'as pas mal de lignes que le générateur de proxy ajoutais et qui me faisait retourner des erreurs 404

# septembre 1, 2008 10:42

cyril a dit :

bug ou pas, je ne sais pas.

Comme tu le dis ce que tu fais n'est pas possible avec un Stream, si svcutil te genere un proxy "valide" je doute qu'il fonctionne correctement.

Si tu veux envoyer plusieurs paramètre avec ton Stream il faut utiliser MessageContract plutot que DataContract.

[MessageContract]

public class FileToUpload

{

   [MessageHeader]

   public string FileName { get; set; }

   [MessageBodyMember]

   public Stream StreamOfFile { get; set; }

}

Il faut également configurer configuré le TransferMode de ton binding en Stream, je ne pense pas que le Buffered fonctionne avec un Stream.

Ainsi avec cette solution cela te permet de travailler en Streaming et non pas avec un Byte[] qui va te faire bien rire quand tu voudras envoyer ton divx de 700Mo ;-)

# septembre 1, 2008 12:12
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Silverlight 3 : Communication et multicast par Kévin Gosse le il y a 9 minutes

- [Perso] Découvertes estivales : Linux (Part I) par Le blog de FremyCompany le il y a 2 heures et 51 minutes

- [Refactoring] ReSharper pour Visual Studio 2010 (Preview) par Thomas Jaskula le il y a 17 heures et 27 minutes

- [Refactoring] Analyser vos exceptions avec ReSharper Exceptional par Thomas Jaskula le il y a 18 heures et 41 minutes

- SharePoint 2007 : patterns & practices SharePoint Guidance par Philippe Sentenac [MVP SharePoint] le 07-03-2009, 09:56

- [Visual Studio 2010] Les tests cases c’est bien, mais je vais devoir tout réécrire ? par Etienne Margraff le 07-03-2009, 09:00

- MVP[Gribouillon].AddYear par The Grib's Lair [Sébastien PICAMELOT - MVP SharePoint] le 07-03-2009, 08:45

- Clinique INSIA - Projet de fin d’Etudes (Silverlight 3 MVVM et OutOfBrowser, WCF, TFS) - Part 1 par David REI le 07-02-2009, 23:38

- C’est la crise ? Bah pourquoi cramer du budget pub alors ? par Nix's Blog le 07-02-2009, 15:31

- Soyons MVP ! par TheSaib .NET blog le 07-02-2009, 12:15