.NET Konsolundan JSON WebService çağırmanın en iyi yolu


90

ASP.Net MVC3'te bir Json dizesi döndüren bir web hizmeti barındırıyorum. Ac # konsol uygulamasından web hizmetini çağırmanın ve dönüşü bir .NET nesnesine ayrıştırmanın en iyi yolu nedir?

Konsol uygulamamda MVC3'e başvurmalı mıyım?

Json.Net'in .NET nesnelerini serileştirmek ve seriyi kaldırmak için bazı güzel yöntemleri var, ancak bir web hizmetinden POST ve GETing değerleri için yollar olduğunu görmüyorum.

Yoksa sadece POSTing ve web hizmetine GETing için kendi yardımcı yöntemimi mi oluşturmalıyım? .Net nesnemi anahtar değer çiftlerine nasıl serileştirebilirim?

Yanıtlar:


143

Web hizmetinden GET için HttpWebRequest kullanıyorum, bu da bana bir JSON dizesi döndürüyor. Bir GET için şuna benzer:

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

Daha sonra dizeyi dinamik olarak ayrıştırmak için JSON.Net kullanıyorum . Alternatif olarak, şu codeplex aracını kullanarak örnek JSON çıktısından C # sınıfını statik olarak oluşturabilirsiniz: http://jsonclassgenerator.codeplex.com/

POST şuna benzer:

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

Web hizmetimizin otomatik testlerinde böyle bir kod kullanıyorum.


JsonClassGenerator harika. Json dizesini geçerek türü güçlü bir şekilde belirlenmiş nesneyi oluşturduğunuz için seriyi kaldırma kolaydır.
AaronLS

Ascii olmayan kümede karakterler varsa, sahip olduğunuz kodun biraz değiştirilmesi gerekir. ContentLength, yayınlanan içeriklerdeki bayt sayısını temsil eder, bu nedenle teknik olarak request.ContentLength, jsonContent.Length değil, byteArray.Length olarak ayarlanmalıdır.
Grady Werner

Encoding.GetEncoding("utf-8")ile değiştirilebilirEncoding.UTF8
JoelFan

Teşekkürler, Bu çok yardımcı oldu
shweta

Yetkilendirme belirtecinin bir parçası olarak ayarlanacaktır, ancak test etmemiz gerekirse başlıkları da geçmemiz gerekebilir. Bu request.Method = "GET"; request.Timeout = 20000; request.ContentType = "application / json"; request.Headers.Add ("Yetkilendirme", "
Simgenizi taşıyın

51

Uzak url'den ve JavaScriptSerializer'dan veya JSON'u bir .NET nesnesine serisini kaldırmak için Json.NET'ten içerik almak için WebClient . Örneğin, JSON yapısını yansıtacak bir model sınıfı tanımlarsınız ve ardından:

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
}

RestSharp gibi satın alabileceğiniz bazı REST istemci çerçeveleri de vardır .


@BrokeMyLegBiking, hangisi? ASPAjax ile ilgisi yok. JavaScriptSerializer sınıfından bahsediyorsanız, System.Web.Extensions derlemesinde .NET'te yerleşik olarak bulunur, böylece hiçbir şey indirmeniz veya yüklemeniz gerekmez.
Darin Dimitrov

Ac # nesnesinin tüm özellik adlarını / özellik değerlerini POST anahtar / değer çiftlerine (veya GET anahtar / değer çiftlerine) dönüştürmenin bir yolu var mı? c # nesnesini web hizmeti yöntemime girdi değeri olarak etkili bir şekilde kullanabilmem için?
BrokeMyLegBiking

@BrokeMyLegBiking, hangi nesneye sahip olduğunuza ve web hizmetinin girdiyi nasıl beklediğine bağlı olacaktır.
Darin Dimitrov

3
RestSharp kitaplığından gerçekten keyif aldım. Bundan bahsettiğin için teşekkürler.
Bryan Ray

1
Daren bunu güncelleyebilir misin, client.downloadstring () artık geçerli değil.
JReam

9

Mevcut cevaplar geçerli yaklaşımlar olsa da, modası geçmiştir. HttpClient , RESTful web servisleri ile çalışmak için modern bir arayüzdür. Bağlantıdaki sayfanın örnekler bölümünü kontrol edin, eşzamansız bir HTTP GET için çok basit bir kullanım durumu vardır.

using (var client = new System.Net.Http.HttpClient())
{
    return await client.GetStringAsync("https://reqres.in/api/users/3"); //uri
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.