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

ASP.NET MVC Discussion :

C#, Android, MVC et Erreur "Java.Net.HttpStatus.BadMethod"


Sujet :

ASP.NET MVC

  1. #1
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2005
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Décembre 2005
    Messages : 482
    Par défaut C#, Android, MVC et Erreur "Java.Net.HttpStatus.BadMethod"
    Salut,
    J'ai créé un simple controller MVC nommé "ProgrammesController" contenant une méthode Get() me permettant de récupérer un datatable (qui fonctionne bien).
    Pour y accéder je tape directement dans mon explorateur : "http://MonServeur/Updator_Service/api/Programmes/" (cela fonctionne)

    j'ai ensuite créé une méthode Get(string id) permettant de renvoyer un datatable ne contenant que les données concernées par cet "id".
    Pour y accéder : "http://MonServeur/Updator_Service/api/Programmes/truc" où "truc" est l'id à envoyer pour filtrer le datatable. (dans l'explorateur cela fonctionne)

    voici le code de ce controller :
    Code : 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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Web.Http;
    using System.Web;
    using System.Data;
     
    namespace Updator.Controllers
    {
        public class ProgrammesController : ApiController
        {
            public System.Data.DataTable Get(string id)
            {
                DataTable dt_Programmes = null;
                DataTable dt_Logiciels = null;
                Outils_BDD.Objets.Connexion_BDD_Collection mesConnexions = null;
     
                Commun.logue("Tentative de récupération des programmes pour la tablette '" + id + "'", "ProgrammesController.RecupProgrammes", "Updator", null);
     
                try
                {
                    mesConnexions = new Outils_BDD.Objets.Connexion_BDD_Collection(HttpContext.Current.Server.MapPath(@"~/Parametres/Connexions.xml"), true);
                }
                catch (Exception ex)
                {
                    Commun.logue("Erreur lors de la connexion à la base 'Applications'", "ProgrammesController.RecupProgrammes", "Updator", ex);
                    return null;
                }
     
                try
                {
                    dt_Programmes = new DataTable("Programmes");
     
                    string requete = "SELECT * FROM Recup_Android_Programmes_Tablettes_V ORDER BY NumSerie, Nom";
                    Outils_BDD.Utiles.RecupCharge_Table(dt_Programmes, requete, HttpContext.Current.Server.MapPath(@"~/Parametres/Programmes.xml"), mesConnexions["Applications"], true, false);
     
                    DataRow[] drs_Programmes = dt_Programmes.Select("NumSerie = '" + id + "'");
                    dt_Logiciels = dt_Programmes.Clone();
                    foreach (DataRow dr_Programme in drs_Programmes)
                    {
                        dt_Logiciels.ImportRow(dr_Programme);
                    }
                }
                catch (Exception ex)
                {
                    Commun.logue("Erreur lors de la récupération des Programmes", "ProgrammesController.Get", "Updator", ex);
                    return null;
                }
     
                return dt_Logiciels;
            }
     
            public System.Data.DataTable Get()
            {
                DataTable dt_Programmes = null;
                Outils_BDD.Objets.Connexion_BDD_Collection mesConnexions = null;
     
                Commun.logue("Tentative de récupération des programmes", "ProgrammesController.Get", "Updator", null);
     
                try
                {
                    mesConnexions = new Outils_BDD.Objets.Connexion_BDD_Collection(HttpContext.Current.Server.MapPath(@"~/Parametres/Connexions.xml"), true);
                }
                catch (Exception ex)
                {
                    Commun.logue("Erreur lors de la connexion à la base 'Applications'", "ProgrammesController.Get", "Updator", ex);
                    return null;
                }
     
                try
                {
                    dt_Programmes = new DataTable("Programmes");
     
                    string requete = "SELECT * FROM Recup_Android_Programmes_Tablettes_V ORDER BY NumSerie, Nom";
                    Outils_BDD.Utiles.RecupCharge_Table(dt_Programmes, requete, HttpContext.Current.Server.MapPath(@"~/Parametres/Programmes.xml"), mesConnexions["Applications"], true, false);
                }
                catch (Exception ex)
                {
                    Commun.logue("Erreur lors de la récupération des Programmes", "ProgrammesController.Get", "Updator", ex);
                    return null;
                }
     
                return dt_Programmes;
            }
        }
    }
    Donc, dans l'explorateur les deux fonctionnent, j'ai ensuite créé (sous android/xamarin) deux bouts de code pour récupérer les données de ce service web.
    Le premier n'ayant qu'à interroger le service web :
    Code : 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
    26
    27
     
    public static DataTable Recup_DataTable_ServiceWeb(string URL_ServiceWeb)
            {
                DataTable retour = null;
                System.IO.Stream maIS;
     
                try
                {
                    HttpURLConnection urlConnection = null;
                    URL url;
                    url = new URL(URL_ServiceWeb);
                    urlConnection = (HttpURLConnection)url.OpenConnection();
                    urlConnection.SetRequestProperty("Content-Type", "application/xml");
                    urlConnection.Connect();
     
                    maIS = urlConnection.InputStream;
     
                    retour = new DataTable();
                    retour.ReadXml(maIS);
                }
                catch (Exception ex)
                {
                    throw new Exception("Erreur avec le service web '" + URL_ServiceWeb + "' : " + ex.Message);
                }
     
                return retour;
            }
    appelé comme ceci : Outils_Android_Reseau.Service_Web.Recup_DataTable_ServiceWeb("http://MonServeur/Updator_Service/api/Programmes");
    Ce code fonctionne parfaitement, je récupère bien mon dataset au complet dans mon programme Android.

    Le deuxième par contre me pose problème; Voici le bout de code :
    Code : 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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
    public static DataTable Recup_DataTable_ServiceWeb(string filtre, string URL_ServiceWeb)
            {
                DataTable retour = null;
                HttpURLConnection urlConnection = null;
     
                try//Envoi Post
                {                
                    URL url = new URL(URL_ServiceWeb);
                    urlConnection = (HttpURLConnection)url.OpenConnection();
                    urlConnection.RequestMethod = "POST";
                    urlConnection.SetRequestProperty("Content-Type", "application/xml");
                    //urlConnection.SetRequestProperty("Content-Type", "text/xml; charset=utf-8");
     
                    urlConnection.DoInput = true;
                    urlConnection.DoOutput = true;
     
                    Stream os = urlConnection.OutputStream;
                    PrintWriter pw = new PrintWriter(os);
                    pw.Print(filtre);
                    pw.Close();
                }
                catch (Exception ex)
                {
                    throw new Exception("Erreur Lors de l'envoi : " + ex.Message);
                }
     
                try//Reception reponse
                {
                    HttpStatus status = urlConnection.ResponseCode;
     
                    if (status != HttpStatus.Ok)
                    {
                        retour = null;
                    }
                    else
                    {
                        retour = new DataTable();
                        retour.ReadXml(urlConnection.InputStream);
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception("Erreur Lors de la réception de la réponse : " + ex.Message);
                }
     
                return retour;
            }
    pour l'exécuter : Outils_Android_Reseau.Service_Web.Recup_DataTable_ServiceWeb(_numSerie, "http://MonServeur/Updator_Service/api/Programmes");

    Quand je l'exécute, "urlConnection.ResponseCode" me renvoie systématiquement "Java.Net.HttpStatus.BadMethod"

    Je tourne en rond depuis plusieurs heures et malgré les exemples similaires sur le web je ne trouve pas l'origine de mon problème
    J'ai tendance à penser que le service web est correct vu que via Firefox j'obtiens bien dans les deux cas un XML représentant mon datatable.
    Et au vu des exemples trouvé sur le web, je ne vois pas ce que j'ai pu louper dans le code coté Android.

    Je ne suis ni un pro d'Android (Seulement 2 programmes assez simples à mon actif) ni d'ASP.Net en général (quelques petits projets simples seulement)

    Quelqu'un peut'il m'éclairer ?

    Merci

  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 : 37
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Billets dans le blog
    3
    Par défaut
    Dans ta fonction Outils_Android_Reseau.Service_Web.Recup_DataTable_ServiceWeb, es-tu sur que ton service Web attend un POST et non un GET ?
    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
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2005
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Décembre 2005
    Messages : 482
    Par défaut
    Salut et merci pour ton intérêt,
    J'avoue que c'est une notion qui m'échappe un peu, pour moi un 'Get' c'est pour recevoir et un 'Post' c'est pour envoyer; alors quand j'envoie une valeur pour en recevoir une autre je suis un peu paumé :p

    Dans tous les cas, j'ai fait varier la ligne "urlConnection.RequestMethod = "GET";" en 'Get', en 'Post' et en rien du tout et le résultat est toujours le même : 'BadMethod'

    J'ai l'impression que c'est la manière d'envoyer la variable (write dans l'outputstream) qui ne fait pas ce que je veux, car, quand je regarde les logs au niveau du service web, je ne vois aucune tentative d'interrogation de ce service :
    "Commun.logue("Tentative de récupération des programmes pour la tablette '" + id + "'", "ProgrammesController.RecupProgrammes", "Updator", null);"
    Alors que quand je l'interroge manuellement depuis Firefox j'obtiens bien mon dataset/Xml et le log est bien créé sur le serveur.

  4. #4
    Expert confirmé

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Billets dans le blog
    21
    Par défaut
    Bonjour,

    Je précise que je ne connais pas le dev sous Android, donc je me contente de mettre en évidence les différences que j'ai pu observer entre le code qui marche et celui qui ne marche pas :
    • un utilise urlConnection.InputStream, l'autre urlConnection.OutputStream ;
    • celui qui fonctionne appelle urlConnection.Connect(), l'autre non ;
    • à quoi correspondent les DoInput ? DoOutput ?

  5. #5
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2005
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Décembre 2005
    Messages : 482
    Par défaut
    Bonjour François,
    Le problème est que les deux fonctions ne font pas la même chose :
    La première ne fait que Récupérer une donnée d'où le fait que je ne reste qu'en GET et que je récupère l'inputsream renvoyée
    La deuxième POST une information puis GET la réponse, d'où l'utilisation dans un premier temps du outputstream pour envoyer ma variable puis du inputstream pour récupérer la réponse.

    Pour l'utilisation du DoOutput j'ai trouvé cette réponse :
    You need to set it to true if you want to send (output) a request body, for example with POST or PUT requests. With GET, you do not usually send a body, so you do not need it.
    mais de toute manière je pense avoir essayé toutes les combinaisons possibles (oui, quand je ne trouve vraiment pas je teste tout ce que je peux 'au pif' :p )

    Pour le Connect() j'ai tenté aussi de le placer un peu partout sans succès.

    Je précise que ce bout de code "Recup_DataTable_ServiceWeb(string filtre, string URL_ServiceWeb)" est le fruit de plusieurs exemples différents mais concordants trouvés sur le web.
    Certains étaient pour Android (mais en Java), certains sur le site de Xamarin, donc en c# mais ne faisant soit que poster soit que récupérer des données.
    Je n'arrive donc pas à trouver d'exemple pour mon problème précis soit : en Xamarin (donc framework Java mais en c#), en POSTant une variable et en 'GETtant' la réponse.

  6. #6
    Expert confirmé

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Billets dans le blog
    21
    Par défaut
    On comprends déjà mieux ce qui doit être fait.

    Une suggestion alors, car l'erreur indique une méthode a priori non supportée (par exemple, l'appel à une méthode POST alors que seul le GET est autorisé).

    Essayer de préciser au niveau des méthodes du contrôleur les VERB qui sont acceptées en utilisant un attribut comme [/c][AcceptVerbs(WebRequestMethods.Http.Get, WebRequestMethods.Http.Post)][/c].

    L'usage de HttpGet et HttpPost est possible mais uniquement pour les méthodes n'acceptant qu'un seul verbe (or là, a priori, il doit y en avoir deux). Quand il y en a plusieurs, il faut utiliser AcceptVerbs.

  7. #7
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2005
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Décembre 2005
    Messages : 482
    Par défaut
    j'ai ajouté ce bout de code avant la définition de la fonction du controller comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    [AcceptVerbs(WebRequestMethods.Http.Get, WebRequestMethods.Http.Post)]
    public System.Data.DataTable Get(string id)
    {...}
    Malheureusement maintenant le WebResponse me renvoie "Not Found" : Grrrr

  8. #8
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2005
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Décembre 2005
    Messages : 482
    Par défaut
    Salut,
    j'étais passé à un autre projet en espérant que quelqu'un trouve la solution à mon problème mais maintenant que l'autre projet est fini je m'y remet

    Après pas mal de tests (tous raté :/) de différentes méthodes trouvées sur le web je suis allé au plus simple.

    Comme la requête fonctionnait quand je la tapais directement dans la zone URL du navigateur, je suis parti du principe que le service web fonctionnait et que c'est l'appel à cette URL qui coinçait.
    Donc au lieu d'écrire dans l'entête ou le corps de la requête j'ai juste concaténé la variable à l'URL :

    Code : 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
    26
    27
    public static DataTable Recup_DataTable_ServiceWeb(string filtre, string URL_ServiceWeb)
            {
                DataTable retour = null;
                System.IO.Stream maIS;
    
                try
                {
                    HttpURLConnection urlConnection = null;
                    URL url;
                    url = new URL(URL_ServiceWeb + "/" + filtre);
                    urlConnection = (HttpURLConnection)url.OpenConnection();
                    urlConnection.SetRequestProperty("Content-Type", "application/xml");
                    urlConnection.Connect();
    
                    maIS = urlConnection.InputStream;
    
                    retour = new DataTable();
                    retour.ReadXml(maIS);
                }
                catch (Exception ex)
                {
                    throw new Exception("Erreur avec le service web '" + URL_ServiceWeb + "' : " + ex.Message);
                }
    
                return retour;
            }
    Cela fonctionne très bien

    Donc, la question que je me pose, avant de clore ce sujet est :
    pourquoi tous les exemples montrent-ils des méthodes complexes pour ajouter une variable à la webrequête en les écrivant dans des 'properties' alors qu'il suffisait juste de coller la variable dans l'URL ?
    Est-ce dû à d'autres 'technologies' de postage/stockage de variables ?

    Je répète que certaines notions web m'échappent complètement malgré les quelques tutoriaux que j'ai suivi.
    Donc si quelqu'un pouvait me diriger vers un tuto bien explicatif du pourquoi du comment ce serait génial.

    Merci

Discussions similaires

  1. erreur out java.net.ConnectException: Connection refused: connect
    Par saadtv4004 dans le forum Services Web
    Réponses: 3
    Dernier message: 08/03/2011, 16h30
  2. Réponses: 0
    Dernier message: 21/02/2011, 11h25
  3. Erreur de compilation java.net.MalformedURLException
    Par karimspace dans le forum Services Web
    Réponses: 4
    Dernier message: 12/04/2007, 11h34
  4. Erreur java.net. ConnectException:
    Par kenny49 dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 27/02/2007, 10h08

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