94

I am hosting a web service in ASP.Net MVC3 which returns a Json string. What is the best way to call the webservice from a c# console application, and parse the return into a .NET object?

Should I reference MVC3 in my console app?

Json.Net has some nice methods for serializing and deserializing .NET objects, but I don't see that it has ways for POSTing and GETing values from a webservice.

Or should I just create my own helper method for POSTing and GETing to the web service? How would I serialize my .net object to key value pairs?

3 Answers 3

146

I use HttpWebRequest to GET from the web service, which returns me a JSON string. It looks something like this for a 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;
    }
}

I then use JSON.Net to dynamically parse the string. Alternatively, you can generate the C# class statically from sample JSON output using this codeplex tool: http://jsonclassgenerator.codeplex.com/

POST looks like this:

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

I use code like this in automated tests of our web service.

Sign up to request clarification or add additional context in comments.

5 Comments

JsonClassGenerator is awesome. Deserialization is easy as you just construct the strongly typed object by passing the json string.
If you have characters in the non-ascii set, the code you have needs to be altered a bit. ContentLength represents the number of bytes in the posted contents, so technically request.ContentLength should be set to byteArray.Length, not jsonContent.Length.
Encoding.GetEncoding("utf-8") can be replaced by Encoding.UTF8
As part of Authorization token will be set but We may have to pass headers also if required to test. Like this request.Method = "GET"; request.Timeout = 20000; request.ContentType = "application/json"; request.Headers.Add("Authorization", "Bearer your token:
Add this attribute if you want to use it as api. [HttpGet("[action]")]
50

WebClient to fetch the contents from the remote url and JavaScriptSerializer or Json.NET to deserialize the JSON into a .NET object. For example you define a model class which will reflect the JSON structure and then:

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
}

There are also some REST client frameworks you may checkout such as RestSharp.

5 Comments

@BrokeMyLegBiking, which one? It has nothing to do with ASPAjax. If you are talking about the JavaScriptSerializer class it is built in .NET in the System.Web.Extensions assembly so you don't have to download or install anything.
Is there a way to turn all the propertynames/property values of a c# object into POST key-value pairs (or GET key-value pairs)? so that I can effectively use the c# object as an input value to my webservice method?
@BrokeMyLegBiking, that will depend on what object you have and how does the web service expects the input.
I've really enjoyed the RestSharp library. Thanks for mentioning that.
Daren can you update this, the client.downloadstring() is no longer viable.
9

Although the existing answers are valid approaches , they are antiquated . HttpClient is a modern interface for working with RESTful web services . Check the examples section of the page in the link , it has a very straightforward use case for an asynchronous HTTP GET .

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.