1. #1
    Membre expérimenté
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    mars 2005
    Messages
    1 019
    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 : 1 019
    Points : 1 571
    Points
    1 571

    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 352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : février 2010
    Messages : 3 352
    Points : 8 862
    Points
    8 862
    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

  3. #3
    Membre expérimenté
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    mars 2005
    Messages
    1 019
    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 : 1 019
    Points : 1 571
    Points
    1 571

    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
    Membre expérimenté
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    mars 2005
    Messages
    1 019
    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 : 1 019
    Points : 1 571
    Points
    1 571

    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 352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : février 2010
    Messages : 3 352
    Points : 8 862
    Points
    8 862
    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

Discussions similaires

  1. Réponses: 1
    Dernier message: 27/04/2012, 17h41
  2. WEB SERVICE récupérer des listes d'objets
    Par kevdep dans le forum 4D
    Réponses: 3
    Dernier message: 13/07/2011, 12h19
  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, 17h26
  4. Consommation de Web Services, comparaison des frameworks
    Par shivack dans le forum Web Services
    Réponses: 1
    Dernier message: 17/07/2008, 15h58
  5. Réponses: 1
    Dernier message: 26/02/2007, 10h44

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