Get Some Rest
This tip is related to this one, which shows how to easily call a REST method that returns a scalar value.
In this case, I will show how you can almost as easily retrieve an array of complex data from a REST call and display the results in a DataGridView
.
Notable: The current DataGridView
is not your unavuncular uncle's DataGridView
- it is very smart and can make sense out of almost anything you assign to it!
So, drag-and-drop or plop a DataGridView
control onto a Windows Form. To use the code below (you'll have to provide your own URI), retain the default name of "dataGridView1
".
The Big Fig / Descendant of Isaac?
As this code uses JSON.NET's JsonConvert()
method and the JArray
type, use NuGet to add Newtonsoft's JSON.NET to your project; NuGet auto-adds newtonsoft.json to your project's References. You just need to install Json.NET via NuGet, and then add two using
clauses, namely: "using Newtonsoft.Json
" and "using Newtonsoft.Json.Linq".
Workable Solution
All it takes to retrieve the results and populate a DataGridView
is code like so:
private void GetRESTData(string uri)
{
try
{
var webRequest = (HttpWebRequest)WebRequest.Create(uri);
var webResponse = (HttpWebResponse)webRequest.GetResponse();
if ((webResponse.StatusCode == HttpStatusCode.OK) && (webResponse.ContentLength > 0))
{
var reader = new StreamReader(webResponse.GetResponseStream());
string s = reader.ReadToEnd();
var arr = JsonConvert.DeserializeObject<JArray>(s);
dataGridView1.DataSource = arr;
}
else
{
MessageBox.Show(string.Format("Status code == {0}", webResponse.StatusCode));
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
...and call it like so:
GetRESTData("http://localhost:28642/api/platypi/1/42");
More Elegant than Lauren Bacall and Joan Fontaine in their Heyday
If you're serious about SOLID, particularly the "S" part (Single Responsibility Principle), you may be turning red or have gone green at the gills, and have steam pouring out your ears to boot as you noticed that the GetRESTData()
method does two things: it retrieves the data from the REST method AND it then populates the DataGridView
!
What if you want to do something else with the returned value - you'd have to write another method -- or, you could refactor this one because of that problem. So, okay, I give in, we'll refactor it. Here's the new code, which returns the results (in a JArray
type) and allows the caller to do what they will with said data:
private JArray GetRESTData(string uri)
{
var webRequest = (HttpWebRequest)WebRequest.Create(uri);
var webResponse = (HttpWebResponse)webRequest.GetResponse();
var reader = new StreamReader(webResponse.GetResponseStream());
string s = reader.ReadToEnd();
return JsonConvert.DeserializeObject<JArray>(s);
}
So, as it should be, GetRESTData()
now knows nothing about any DataGridView
, and it only does one thing (and does it well, I might add). And here's how we can now call the new and improved GetRESTData()
method:
try
{
dataGridView1.DataSource = GetRESTData("http://localhost:28642/api/inventoryitems/1/10");
}
catch (WebException webex)
{
MessageBox.Show("Es gab so ein Schlamassel! ({0})", webex.Message);
}
Now that it has been solidified and made safer for reuse, you can call GetRESTData()
and do something else with the returned data: parse it, slice it, dice it, or decrypt it and sell it all to the NSA, NASA, or PITA -- or even sprinkle it with oregano and garlic and have it on Pita bread. Happy now?
The Wisdom of the Crowd
Thanks to Matthew, who provided an even better take on my original refactor here.
Rational Exuberance and Random Generosity
If you like this tip, go outside, do a somersault, summerset, salto, or salto de gozo and/or click your heels like Zorba the Greco-Roman Architect, and give $5 to the hungriest-looking person you see.