Najlepszy sposób wywołania JSON WebService z konsoli .NET

90

Hostuję usługę sieci Web w ASP.Net MVC3, która zwraca ciąg Json. Jaki jest najlepszy sposób wywołania usługi sieciowej z aplikacji konsoli ac # i przeanalizowania wyniku zwracanego do obiektu .NET?

Czy powinienem odwoływać się do MVC3 w mojej aplikacji konsoli?

Json.Net ma kilka fajnych metod serializacji i deserializacji obiektów .NET, ale nie widzę, że ma sposoby na POST i pobieranie wartości z usługi sieciowej.

A może powinienem po prostu utworzyć własną metodę pomocniczą dla POSTINGU i POBIERANIA do usługi internetowej? Jak mogę serializować mój obiekt .net do par klucz-wartość?

BrokeMyLegBiking
źródło

Odpowiedzi:

143

Używam HttpWebRequest do POBIERANIA z usługi internetowej, która zwraca mi ciąg JSON. W przypadku GET wygląda to mniej więcej tak:

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

Następnie używam JSON.Net do dynamicznej analizy ciągu. Alternatywnie możesz wygenerować klasę C # statycznie na podstawie przykładowych danych wyjściowych JSON przy użyciu tego narzędzia codeplex: http://jsonclassgenerator.codeplex.com/

POST wygląda tak:

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

Używam takiego kodu w automatycznych testach naszego serwisu internetowego.

GarethOwen
źródło
JsonClassGenerator jest niesamowity. Deserializacja jest łatwa, ponieważ po prostu konstruujesz obiekt o jednoznacznie określonym typie, przekazując ciąg json.
AaronLS,
Jeśli masz znaki w zestawie innym niż ASCII, kod, który masz, musi zostać nieco zmieniony. ContentLength reprezentuje liczbę bajtów w opublikowanej zawartości, więc z technicznego punktu widzenia request.ContentLength należy ustawić na wartość byteArray.Length, a nie jsonContent.Length.
Grady Werner
Encoding.GetEncoding("utf-8")może zostać zastąpiony przezEncoding.UTF8
JoelFan
Dzięki, to jest bardzo pomocne
shweta
Jako część zostanie ustawiony token autoryzacji, ale może być konieczne przekazanie nagłówków również, jeśli będzie to wymagane do przetestowania. Podobnie jak to request.Method = "GET"; request.Timeout = 20000; request.ContentType = "application / json"; request.Headers.Add ("Authorization", "Bearer your token:
Kurkula
51

WebClient, aby pobrać zawartość ze zdalnego adresu URL i JavaScriptSerializer lub Json.NET w celu deserializacji JSON do obiektu .NET. Na przykład definiujesz klasę modelu, która będzie odzwierciedlać strukturę JSON, a następnie:

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
}

Istnieją również struktury klienta REST, które możesz pobrać, takie jak RestSharp .

Darin Dimitrov
źródło
@BrokeMyLegBiking, który? Nie ma to nic wspólnego z ASPAjaxem. Jeśli mówisz o klasie JavaScriptSerializer, jest ona wbudowana w .NET w zestawie System.Web.Extensions, więc nie musisz niczego pobierać ani instalować.
Darin Dimitrov
Czy istnieje sposób na przekształcenie wszystkich nazw właściwości / wartości właściwości obiektu ac # w pary klucz-wartość typu POST (lub pary klucz-wartość GET)? tak, że mogę skutecznie używać obiektu C # jako wartości wejściowej do mojej metody usługi sieci web?
BrokeMyLegBiking
@BrokeMyLegBiking, to będzie zależeć od posiadanego obiektu i tego, jak usługa internetowa oczekuje danych wejściowych.
Darin Dimitrov
3
Biblioteka RestSharp naprawdę mi się podobała. Dzięki, że o tym wspomniałeś.
Bryan Ray,
1
Daren, czy możesz to zaktualizować, client.downloadstring () nie jest już opłacalny.
JReam
9

Chociaż istniejące odpowiedzi są poprawnymi podejściami, są one przestarzałe. HttpClient to nowoczesny interfejs do pracy z usługami sieciowymi RESTful. Sprawdź sekcję przykładów strony w linku, ma bardzo prosty przypadek użycia asynchronicznego HTTP GET.

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