Der beste Weg, um einen JSON-Webdienst von einer .NET-Konsole aus aufzurufen

89

Ich hoste einen Webdienst in ASP.Net MVC3, der eine Json-Zeichenfolge zurückgibt. Was ist der beste Weg, um den Webservice von einer ac # -Konsolenanwendung aus aufzurufen und die Rückgabe in ein .NET-Objekt zu analysieren?

Sollte ich in meiner Konsolen-App auf MVC3 verweisen?

Json.Net hat einige nette Methoden zum Serialisieren und Deserialisieren von .NET-Objekten, aber ich sehe keine Möglichkeiten zum POSTEN und Abrufen von Werten von einem Webservice.

Oder sollte ich einfach meine eigene Hilfsmethode zum POSTEN und GETING zum Webdienst erstellen? Wie würde ich mein .net-Objekt in Schlüsselwertpaare serialisieren?

BrokeMyLegBiking
quelle

Antworten:

141

Ich verwende HttpWebRequest, um vom Webdienst abzurufen, der mir eine JSON-Zeichenfolge zurückgibt. Für ein GET sieht es ungefähr so ​​aus:

// 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;
    }
}

Ich benutze dann JSON.Net , um den String dynamisch zu analysieren. Alternativ können Sie die C # -Klasse statisch aus der JSON-Beispielausgabe mit diesem Codeplex-Tool generieren: http://jsonclassgenerator.codeplex.com/

POST sieht so aus:

// 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
    }
}

Ich verwende solchen Code in automatisierten Tests unseres Webservices.

GarethOwen
quelle
JsonClassGenerator ist großartig. Die Deserialisierung ist einfach, da Sie das stark typisierte Objekt einfach durch Übergeben der JSON-Zeichenfolge erstellen.
AaronLS
Wenn Sie Zeichen im Nicht-ASCII-Satz haben, muss der Code, den Sie haben, etwas geändert werden. ContentLength stellt die Anzahl der Bytes in den veröffentlichten Inhalten dar, also technisch angefordert. ContentLength sollte auf byteArray.Length und nicht auf jsonContent.Length festgelegt werden.
Grady Werner
Encoding.GetEncoding("utf-8")kann ersetzt werden durchEncoding.UTF8
JoelFan
Danke, das ist sehr hilfreich
Shweta
Im Rahmen der Autorisierung wird ein Token gesetzt, aber wir müssen möglicherweise auch Header übergeben, wenn dies zum Testen erforderlich ist. Gefällt mir diese Anfrage.Method = "GET"; request.Timeout = 20000; request.ContentType = "application / json"; request.Headers.Add ("Authorization", "Bearer your token:
Kurkula
51

WebClient zum Abrufen des Inhalts von der Remote-URL und JavaScriptSerializer oder Json.NET zum Deserialisieren des JSON in ein .NET-Objekt. Zum Beispiel definieren Sie eine Modellklasse, die die JSON-Struktur widerspiegelt, und dann:

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
}

Es gibt auch einige REST-Client-Frameworks, die Sie möglicherweise auschecken, z. B. RestSharp .

Darin Dimitrov
quelle
@BrokeMyLegBiking, welches? Es hat nichts mit ASPAjax zu tun. Wenn Sie über die JavaScriptSerializer-Klasse sprechen, wird sie in .NET in der System.Web.Extensions-Assembly erstellt, sodass Sie nichts herunterladen oder installieren müssen.
Darin Dimitrov
Gibt es eine Möglichkeit, alle Eigenschafts- / Eigenschaftswerte des ac # -Objekts in POST-Schlüssel-Wert-Paare (oder GET-Schlüssel-Wert-Paare) umzuwandeln? damit ich das c # -Objekt effektiv als Eingabewert für meine Webservice-Methode verwenden kann?
BrokeMyLegBiking
@BrokeMyLegBiking, das hängt davon ab, welches Objekt Sie haben und wie der Webdienst die Eingabe erwartet.
Darin Dimitrov
3
Ich habe die RestSharp-Bibliothek wirklich genossen. Danke, dass du das erwähnt hast.
Bryan Ray
1
Daren können Sie dies aktualisieren, der client.downloadstring () ist nicht mehr funktionsfähig.
JReam
9

Obwohl die vorhandenen Antworten gültige Ansätze sind, sind sie veraltet. HttpClient ist eine moderne Schnittstelle für die Arbeit mit RESTful-Webdiensten. Überprüfen Sie den Beispielabschnitt der Seite im Link. Es gibt einen sehr einfachen Anwendungsfall für ein asynchrones HTTP-GET.

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