IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Web service attendant des bouts de fichier


Sujet :

C#

  1. #1
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 674
    Points : 5 259
    Points
    5 259
    Par défaut Web service attendant des bouts de fichier
    Bonjour,

    Je dois faire appel à une méthode de web service de type Web API REST dont la signature est la suivante :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    [HttpPost]
    [ResponseType(typeof(Int32))]
    IHttpActionResult InsertFilePart(String headerId, HttpPostedFile data)

    La documentation indique que sur un fichier volumineux, je dois au préalable le découper en paquet de 2Mo.
    Le FileId est l'identifiant du fichier. Le paramètre "data" correspond à un bout de fichier.
    Je suis sensé appeler la méthode plusieurs fois avec le même FileId tant que tout les bouts de fichiers ne sont pas envoyés.

    J'ai donc découpé mon fichier en tableau de Byte mais je ne sais parvient pas à appeler la méthode correctement.

    J'ai essayé avec WebClient et sa méthode UploadFile mais ça prend le chemin en paramètre et donc envoie le fichier complet et ne peux donc pas correspondre.
    J'ai essayé de passer le FileId dans l'URL et d'appeler la méthode WebClient.UploadData mais j'ai une erreur 500.
    J'ai essayé de faire du Mutlipart/Form-data avec HttpClient et MultipartFormDataContent, j'ai le message Can't bind multiple parameters ('header' and 'data') to the request's content..
    J'ai essayé de le faire à l'ancienne en construisant moi même une HttpWebRequest et un contenu Mutlipart/Form-data, erreur 500.

    Sur leur serveur de log, aucune trace de mes tentatives.
    J'image que ce que j'envoie ne correspond pas à la signature et que je n'arrive même pas jusqu'au mécanisme de log.
    Une idée sur comment appeler cette méthode ?

  2. #2
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Points : 9 743
    Points
    9 743
    Billets dans le blog
    3
    Par défaut
    WebAPI ne gere pas de multiples parametres en POST. Je considere que les 2 parametres sont prefixes par [FromBody] :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    [HttpPost]
    [ResponseType(typeof(Int32))]
    IHttpActionResult InsertFilePart([FromBody] String headerId, [FromBody] HttpPostedFile data)
    Il faut creer un seul model, par exemple :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public class TonModel
    {
        public string HeaderId { get; set; }
     
        public HttpPostedFile Data { get; set; }
    }
    Ensuite il suffit de le passer en parametre :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    IHttpActionResult InsertFilePart([FromBody] TonModel data)

    Pour reference, tu peux consulter ce lien qui propose d'autres alternatives : Passing multiple POST parameters to Web API Controller Methods.

    Si tu n'arrives pas a resoudre, poste le contenu des messages d'erreur c'est toujours utile.
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

  3. #3
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 674
    Points : 5 259
    Points
    5 259
    Par défaut
    Bonjour et merci,

    Il n'y a pas de FromBody dans la signature.
    Par contre j'ai essayé de passer l'id dans l'URL et je vais plus loin.

    Voici mes dernière tentatives :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    using (HttpClient client = new HttpClient())
    {
        String boundary = "--------" + DateTime.Now.ToString("MMddyyHHmmssfff");
     
        client.DefaultRequestHeaders.Add("Accept", "text/json");
        client.DefaultRequestHeaders.Add("Authorization", "bearer " + token.access_token);
     
        using (MultipartFormDataContent content = new MultipartFormDataContent())
        {
            content.Add(new StreamContent(new MemoryStream(blocks.ElementAt(i))));
            String uri = "http://URITestUpload/InsertFilePart?headerId=" + id;
            using (Task<HttpResponseMessage> task = client.PostAsync(uri, content))
            {
                task.Wait();
                HttpResponseMessage response = task.Result;
     
                String test = response.Content.ReadAsStringAsync().Result;
                if (!string.IsNullOrWhiteSpace(test))
                {
                    MessageBox.Show(test);
                }
            }
     
        }
    }

    Cela me renvoie l'erreur suivante :
    {"message":"The request entity's media type 'multipart/form-data' is not supported for this resource.","exceptionMessage":"No MediaTypeFormatter is available to read an object of type 'HttpPostedFile' from content with media type 'multipart/form-data'.","exceptionType":"System.Net.Http.UnsupportedMediaTypeException","stackTrace":" à System.Net.Http.HttpContentExtensions.ReadAsAsync[T](HttpContent content, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)\r\n à System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)"}
    J'en ai déduis qu'il ne fallait pas utiliser le 'multipart/form-data'.

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    String uri = "http://URITestUpload/InsertFilePart?headerId=" + id;
     
    using (HttpClient client = new HttpClient())
    {
        client.DefaultRequestHeaders.Add("Accept", "text/json");
        client.DefaultRequestHeaders.Add("Authorization", "bearer " + token.access_token);
     
        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri);
        request.Content = new StreamContent(new MemoryStream(blocks.ElementAt(i)));
     
        using (Task<HttpResponseMessage> task = client.SendAsync(request))
        {
            task.Wait();
            HttpResponseMessage response = task.Result;
     
            String test = response.Content.ReadAsStringAsync().Result;
            if (!string.IsNullOrWhiteSpace(test))
            {
                MessageBox.Show(test);
            }
        }
    }

    {"message":"The request contains an entity body but no Content-Type header. The inferred media type 'application/octet-stream' is not supported for this resource.","exceptionMessage":"No MediaTypeFormatter is available to read an object of type 'HttpPostedFile' from content with media type 'application/octet-stream'.","exceptionType":"System.Net.Http.UnsupportedMediaTypeException","stackTrace":" à System.Net.Http.HttpContentExtensions.ReadAsAsync[T](HttpContent content, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)\r\n à System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)"}
    Si je lui renseigne un content-type j'ai à peu près la même erreur.

  4. #4
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 674
    Points : 5 259
    Points
    5 259
    Par défaut
    Bon au final, je ne vois pas de moyen de passer un HttpPostedFile, si quelqu'un en connaît un, je suis preneur.

    Plus je fais de recherches, plus j'en viens à considérer que ce n'est définitivement pas une pratique courante.
    La personne en charge du développement de cette API m'affirme que si.
    Elle n'a cependant pas pu me dire comment faire parce qu'elle ne l'a jamais fait....
    En gros, elle me donne cette foutue méthode qu'elle n'est pas capable de consommer elle-même parce que son métier consiste à publier des API REST et pas à les consommer...

    Après m'être fâché avec cette personne, elle a bien voulu me publier une méthode prenant en paramètre un DTO pour passer l'id et tableau de Byte.
    J'ai donc une solution mais je crains qu'elle ne soit que provisoire.

    Je laisse donc cette discussion ouverte pour le moment...

  5. #5
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Points : 9 743
    Points
    9 743
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par popo Voir le message
    Après m'être fâché avec cette personne, elle a bien voulu me publier une méthode prenant en paramètre un DTO pour passer l'id et tableau de Byte.
    J'ai donc une solution mais je crains qu'elle ne soit que provisoire.
    C'est tout simplement la bonne facon de proceder, comme je l'ai indique dans mon premier post sur cette discussion : "WebAPI ne gere pas de multiples parametres en POST".
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

Discussions similaires

  1. Réponses: 1
    Dernier message: 27/04/2012, 16h41
  2. WEB SERVICE récupérer des listes d'objets
    Par kevdep dans le forum 4D
    Réponses: 3
    Dernier message: 13/07/2011, 11h19
  3. Lenteur avec un Web service et des pie charts
    Par laurent_diep dans le forum Silverlight
    Réponses: 10
    Dernier message: 25/03/2009, 16h26
  4. Consommation de Web Services, comparaison des frameworks
    Par shivack dans le forum Services Web
    Réponses: 1
    Dernier message: 17/07/2008, 14h58
  5. Réponses: 1
    Dernier message: 26/02/2007, 09h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo