Best way to call a JSON WebService from a .NET Console - c#

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?

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.

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.

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
}

Related

Limiting a JSON string response from an API to select attributes

Currently, I am using a [WebMethod] to call an API and get the response as a JSON string.
public string GetFloodData()
{ ...
WebRequest requestObj = WebRequest.Create(url);
requestObj.Method = "GET";
requestObj.ContentType = "application/json";
responseObj = (HttpWebResponse)requestObj.GetResponse();
using (Stream stream = responseObj.GetResponseStream())
{
StreamReader sr = new StreamReader(stream);
strresult = sr.ReadToEnd();
sr.Close();
}
return strresult;
...
}
When I call GetFloodData(), I get the following response in the browser:
<string xmlns="http://tempuri.org/">
{"ListEvents":
[{"EventID":1,"EventName":"Debby2000","State":"PR","EventType":"Tropical or
Extratropical","Days":5,"LSTStart":"\/Date(9666432000000000)\/",
"LSTEnd":"\/Dat e(967075200000-0000)\/"}, {...}....]}
At this point (before I parse it as a formal JSON Object), I just want to eliminate the stuff I don't want ("Days","LSTStart", and "LSTEnd") and keep what I want. How would I limit what attributes are returned in my response?
You can de-serialise it with a class, and in that class, you can write only the variables you do want to keep. Although, keep the structure of the Json and the class as same. Variables can be missing, but the structure should be the same

First Step with Riot API in C#

I am learning C# and want to use the Riot API. I just want to receive that:
{
"type":"champion",
"version":"6.1.1",
"data":{
"Thresh":{
"id":412,
"key":"Thresh",
"name":"Thresh",
"title":"the Chain Warden"
},
"Aatrox":{
"id":266,
"key":"Aatrox",
"name":"Aatrox",
"title":"the Darkin Blade"
},...
I found this here: Deserialize JSON from Riot API C#
Can someone help me? I have no Idea what to do.
sincerly
MasterR8
PS: I already googled 3 hours...
If you want to get the json string try this, this take a URL and tries to do the request and returns the response. You can find the url in the sandbox mode provided on the riot API site.
using System.Net;
using System.IO;
public 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, Encoding.UTF8);
return reader.ReadToEnd();
}
}
catch (WebException ex)
{
WebResponse errorResponse = ex.Response;
using (Stream responseStream = errorResponse.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
String errorText = reader.ReadToEnd();
}
throw;
}
}
This is the easy part :) mapping the response to a POCO is what annoys me the most. If anybody reads this and has a good solution plzz link me.

C# Web API REST Service POST

I originally asked a question regarding a WCF web service that I was trying to write and then found that the ASP.net web API was more appropriate to my needs, due to some feedback on here.
I've now found a good tutorial that tells me how to create a simple REST service using Web API which works well pretty much out of the box.
My question
I have a POST method in my REST service server:
// POST api/values/5
public string Post([FromBody]string value)
{
return "Putting value: " + value;
}
I can POST to this using POSTER and also my C# client code.
However the bit I don't understand is why I have to prepend an '=' sign to the POST data so that it reads: "=Here is my data which is actually a JSON string"; rather than just sending: "Here is my data which is actually a JSON string";
My C# Client that talks to the REST service is written as follows:
public string SendPOSTRequest(string sFunction, string sData)
{
string sResponse = string.Empty;
// Create the request string using the data provided
Uri uriRequest = GetFormRequest(m_sWebServiceURL, sFunction, string.Empty);
// Data to post
string sPostData = "=" + sData;
// The Http Request obj
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uriRequest);
request.Method = m_VERB_POST;
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
Byte[] byteArray = encoding.GetBytes(sPostData);
request.ContentLength = byteArray.Length;
request.ContentType = m_APPLICATION_FORM_URLENCODED;
try
{
using (Stream dataStream = request.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
sResponse = reader.ReadToEnd();
}
}
}
catch (WebException ex)
{
//Log exception
}
return sResponse;
}
private static Uri GetFormRequest(string sURL, string sFunction, string sParam)
{
StringBuilder sbRequest = new StringBuilder();
sbRequest.Append(sURL);
if ((!sURL.EndsWith("/") &&
(!string.IsNullOrEmpty(sFunction))))
{
sbRequest.Append("/");
}
sbRequest.Append(sFunction);
if ((!sFunction.EndsWith("/") &&
(!string.IsNullOrEmpty(sParam))))
{
sbRequest.Append("/");
}
sbRequest.Append(sParam);
return new Uri(sbRequest.ToString());
}
Is anybody able to explain why I have to prepend the '=' sign as in the above code (string sPostData = "=" + sData;)?
Many thanks in advance!
The content type x-www-form-urlencoded is a key-value format. With form bodies you are only able to read a single simple type from a request body. As a name is expected, but in this case not allowed, you have to prefix the equal sign to indicate that there is no name with the followed value.
However, you should lean away from accepting simple types within the body of your web-api controller actions.
You are limited to only a single simple type if you attempt to pass data in the body of an HttpPost/HttpPut without directly implementing your own MediaTypeFormatter, which is unlikely to be reliable. Creating a light-weight complex type is generally much more preferable, and will make interoperating with other content-types, like application/json, much easier.

Valence D2l: Course Offrings from url using org unit id

I'm currently working on getting course offerings from org unit id using c#.
I'm brand-new to D2L valence. I have app ID/key pair and user ID/Key pair.
I am going to enter org unit id, get json response, parse the json response in c#, and output the associated course code and name.
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, Encoding.UTF8);
return reader.ReadToEnd();
}
}
catch (WebException ex)
{
WebResponse errorResponse = ex.Response;
using (Stream responseStream = errorResponse.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
String errorText = reader.ReadToEnd();
// log errorText
}
throw;
}
}
this is my GET code. And, I'm trying to call it. The url and the main code are the following:
string url = "http://test.ca/d2l/api/lp/1.0/courses/644849";
GET(url);
The problem is I'm getting error says: The remote server returned an error: (403)Forbidden.
Also, I've tried this url:
string url = "http://lms.valence.desire2learn.com/d2l/api/lp/1.0/courses/644849";
This time, I got this error (Object reference not set to an instance of an object.)
I have app id/key pair and user id/key pair.
What should I do to solve this problem and end up with getting course offerings.
Thanks in advance, Phillip
The reason you're getting a 403 forbidden is because you are not sending the appropriate identifiers and signatures on your query string to allow your request to be authenticated (see http://docs.valence.desire2learn.com/basic/auth.html#id4).
If you are using C#, I'd recommend using the Valence SDK located on Nuget to generate appropriate URLs. Take a look at https://github.com/Brightspace/valence-sdk-dotnet/tree/master/samples/Basic for a sample project using the SDK, specifically, https://github.com/Brightspace/valence-sdk-dotnet/blob/master/samples/Basic/Basic/Controllers/HomeController.cs, shows how you can use the SDK methods to make a whoami request.

HTTP POST in .NET doesn't work

I've got a problem with creating an HTTP post request in .NET. When I do this request in ruby it does work.
When doing the request in .NET I get following error:
<h1>FOXISAPI call failed</h1><p><b>Progid is:</b> carejobs.carejobs
<p><b>Method is:</b> importvacature/
<p><b>Parameters are:</b>
<p><b> parameters are:</b> vacature.deelnemernr=478
</b><p><b>GetIDsOfNames failed with err code 80020006: Unknown name.
</b>
Does anyone knows how to fix this?
Ruby:
require 'net/http'
url = URI.parse('http://www.carejobs.be/scripts/foxisapi.dll/carejobs.carejobs.importvacature')
post_args = {
'vacature.deelnemernr' => '478',
}
resp, data = Net::HTTP.post_form(url, post_args)
print resp
print data
C#:
Uri address = new Uri(url);
// Create the web request
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
// Set type to POST
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
// Create the data we want to send
StringBuilder data = new StringBuilder();
data.Append("vacature.deelnemernr=" + HttpUtility.UrlEncode("478"));
// Create a byte array of the data we want to send
byte[] byteData = UTF8Encoding.UTF8.GetBytes(data.ToString());
// Set the content length in the request headers
request.ContentLength = byteData.Length;
// Write data
using (Stream postStream = request.GetRequestStream())
{
postStream.Write(byteData, 0, byteData.Length);
}
// Get response
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
// Console application output
result = reader.ReadToEnd();
}
return result;
Don't you need the ? after the URL in order to do a post with parameters? I think that Ruby hides this behind the scenes.
I found the problem! The url variable in the C# code was "http://www.carejobs.be/scripts/foxisapi.dll/carejobs.carejobs.importvacature/"
It had to be "http://www.carejobs.be/scripts/foxisapi.dll/carejobs.carejobs.importvacature" without the backslash.

Categories

Resources