Meilleur moyen d'appeler un WebService JSON à partir d'une console .NET

89

J'héberge un service Web dans ASP.Net MVC3 qui renvoie une chaîne Json. Quelle est la meilleure façon d'appeler le service Web à partir de l'application console ac # et d'analyser le retour dans un objet .NET?

Dois-je référencer MVC3 dans mon application console?

Json.Net a quelques méthodes intéressantes pour sérialiser et désérialiser des objets .NET, mais je ne vois pas qu'il a des moyens de POSTER et d'obtenir des valeurs à partir d'un service Web.

Ou devrais-je simplement créer ma propre méthode d'aide pour le POST et l'accès au service Web? Comment sérialiser mon objet .net en paires clé / valeur?

BrokeMyLegBiking
la source

Réponses:

142

J'utilise HttpWebRequest pour OBTENIR du service Web, qui me renvoie une chaîne JSON. Cela ressemble à quelque chose comme ça pour un GET:

// Returns JSON string
string GET(string url) 
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    try {
        WebResponse response = request.GetResponse();
        using (Stream responseStream = response.GetResponseStream()) {
            StreamReader reader = new StreamReader(responseStream, System.Text.Encoding.UTF8);
            return reader.ReadToEnd();
        }
    }
    catch (WebException ex) {
        WebResponse errorResponse = ex.Response;
        using (Stream responseStream = errorResponse.GetResponseStream())
        {
            StreamReader reader = new StreamReader(responseStream, System.Text.Encoding.GetEncoding("utf-8"));
            String errorText = reader.ReadToEnd();
            // log errorText
        }
        throw;
    }
}

J'utilise ensuite JSON.Net pour analyser dynamiquement la chaîne. Vous pouvez également générer la classe C # de manière statique à partir d'un exemple de sortie JSON à l'aide de cet outil codeplex: http://jsonclassgenerator.codeplex.com/

POST ressemble à ceci:

// POST a JSON string
void POST(string url, string jsonContent) 
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "POST";

    System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
    Byte[] byteArray = encoding.GetBytes(jsonContent);

    request.ContentLength = byteArray.Length;
    request.ContentType = @"application/json";

    using (Stream dataStream = request.GetRequestStream()) {
        dataStream.Write(byteArray, 0, byteArray.Length);
    }
    long length = 0;
    try {
        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
            length = response.ContentLength;
        }
    }
    catch (WebException ex) {
        // Log exception and throw as for GET example above
    }
}

J'utilise un code comme celui-ci dans les tests automatisés de notre service Web.

GarethOwen
la source
JsonClassGenerator est génial. La désérialisation est facile car vous construisez simplement l'objet fortement typé en passant la chaîne json.
AaronLS du
Si vous avez des caractères dans le jeu non-ascii, le code que vous avez doit être légèrement modifié. ContentLength représente le nombre d'octets dans le contenu publié, donc techniquement request.ContentLength doit être défini sur byteArray.Length et non sur jsonContent.Length.
Grady Werner
Encoding.GetEncoding("utf-8")peut être remplacé parEncoding.UTF8
JoelFan
Merci, Ceci est très utile
shweta
Dans le cadre de l'autorisation, le jeton sera défini, mais nous devrons peut-être passer des en-têtes également si nécessaire pour tester. Comme cette request.Method = "GET"; request.Timeout = 20000; request.ContentType = "application / json"; request.Headers.Add ("Authorization", "Bearer your token:
Kurkula
51

WebClient pour récupérer le contenu de l'url distante et JavaScriptSerializer ou Json.NET pour désérialiser le JSON en un objet .NET. Par exemple, vous définissez une classe de modèle qui reflétera la structure JSON, puis:

using (var client = new WebClient())
{
    var json = client.DownloadString("http://example.com/json");
    var serializer = new JavaScriptSerializer();
    SomeModel model = serializer.Deserialize<SomeModel>(json);
    // TODO: do something with the model
}

Il existe également des frameworks client REST que vous pouvez extraire tels que RestSharp .

Darin Dimitrov
la source
@BrokeMyLegBiking, lequel? Cela n'a rien à voir avec ASPAjax. Si vous parlez de la classe JavaScriptSerializer, elle est intégrée à .NET dans l'assembly System.Web.Extensions afin que vous n'ayez rien à télécharger ou à installer.
Darin Dimitrov
Existe-t-il un moyen de transformer tous les noms de propriété / valeurs de propriété de l'objet ac # en paires clé-valeur POST (ou en paires clé-valeur GET)? afin que je puisse utiliser efficacement l'objet c # comme valeur d'entrée dans ma méthode de service Web?
BrokeMyLegBiking
@BrokeMyLegBiking, cela dépendra de l'objet que vous possédez et de la manière dont le service Web attend l'entrée.
Darin Dimitrov
3
J'ai vraiment apprécié la bibliothèque RestSharp. Merci d'avoir mentionné cela.
Bryan Ray
1
Daren pouvez-vous mettre à jour cela, le client.downloadstring () n'est plus viable.
JReam
9

Bien que les réponses existantes soient des approches valables, elles sont désuètes. HttpClient est une interface moderne pour travailler avec les services Web RESTful. Consultez la section des exemples de la page dans le lien, elle présente un cas d'utilisation très simple pour un HTTP GET asynchrone.

using (var client = new System.Net.Http.HttpClient())
{
    return await client.GetStringAsync("https://reqres.in/api/users/3"); //uri
}
LostNomad311
la source