Melhor maneira de chamar um JSON WebService a partir de um console .NET

89

Estou hospedando um serviço da web em ASP.Net MVC3 que retorna uma string Json. Qual é a melhor maneira de chamar o serviço da web de um aplicativo de console ac # e analisar o retorno em um objeto .NET?

Devo fazer referência a MVC3 em meu aplicativo de console?

Json.Net tem alguns métodos legais para serializar e desserializar objetos .NET, mas eu não vejo que ele tenha maneiras de POSTar e obter valores de um serviço da web.

Ou devo apenas criar meu próprio método auxiliar para POSTAR e obter o serviço da Web? Como eu serializaria meu objeto .net em pares de valores-chave?

BrokeMyLegBiking
fonte

Respostas:

142

Eu uso HttpWebRequest para GET do serviço da web, que me retorna uma string JSON. É algo assim para um 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;
    }
}

Em seguida, uso JSON.Net para analisar dinamicamente a string. Como alternativa, você pode gerar a classe C # estaticamente a partir da saída JSON de amostra usando esta ferramenta codeplex: http://jsonclassgenerator.codeplex.com/

POST se parece com isto:

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

Eu uso um código como este em testes automatizados de nosso serviço web.

GarethOwen
fonte
JsonClassGenerator é incrível. A desserialização é fácil, pois você apenas constrói o objeto fortemente tipado passando a string json.
AaronLS
Se você tiver caracteres no conjunto não-ascii, o código que você tem precisa ser um pouco alterado. ContentLength representa o número de bytes no conteúdo postado, portanto, tecnicamente, request.ContentLength deve ser definido como byteArray.Length, não jsonContent.Length.
Grady Werner
Encoding.GetEncoding("utf-8")pode ser substituído porEncoding.UTF8
JoelFan
Obrigado, Isso é muito útil
shweta
Como parte do token de autorização será definido, mas talvez tenhamos que passar os cabeçalhos também se necessário para testar. Como este request.Method = "GET"; request.Timeout = 20000; request.ContentType = "application / json"; request.Headers.Add ("Authorization", "Bearer your token:
Kurkula
51

WebClient para buscar o conteúdo do url remoto e JavaScriptSerializer ou Json.NET para desserializar o JSON em um objeto .NET. Por exemplo, você define uma classe de modelo que refletirá a estrutura JSON e então:

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
}

Existem também algumas estruturas de cliente REST que você pode verificar, como RestSharp .

Darin Dimitrov
fonte
@BrokeMyLegBiking, qual? Não tem nada a ver com ASPAjax. Se você está falando sobre a classe JavaScriptSerializer, ela é construída em .NET no assembly System.Web.Extensions, portanto, você não precisa baixar ou instalar nada.
Darin Dimitrov
Existe uma maneira de transformar todos os nomes de propriedade / valores de propriedade de um objeto c # em pares de valor-chave POST (ou pares de valor-chave GET)? para que eu possa usar efetivamente o objeto c # como um valor de entrada para meu método de serviço da web?
BrokeMyLegBiking
@BrokeMyLegBiking, que dependerá de qual objeto você possui e de como o serviço web espera a entrada.
Darin Dimitrov
3
Eu realmente gostei da biblioteca RestSharp. Obrigado por mencionar isso.
Bryan Ray
1
Daren, você pode atualizar isso, o client.downloadstring () não é mais viável.
JReam
9

Embora as respostas existentes sejam abordagens válidas, elas são antiquadas. HttpClient é uma interface moderna para trabalhar com serviços da Web RESTful. Verifique a seção de exemplos da página no link, ele tem um caso de uso muito simples para um HTTP GET assíncrono.

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