11ptMan
asked on
How do I Pass JSON Payload with WebClient in C#
I'm fairly new to web services. I've used them before but in all the cases so far all the request data was passed in the url. I'm trying to work with a web service now and have run in to a new situation. In one case the data is passed in the url and I was successful in writting a routine to consume it. But the other one has me stumped. I've done several searches with little resolve. Basicly I need to know how to add a payload to the JSON request.( See Notes in source code below). The BLS site provided some assitance but I'm using the WebClient in VS2010 and can't find the equivilent to this part of their Apache HTTP Commons Client example:
Do I need to switch away from the WebClient Object and use the HttpWebRequest object to have this work?
Here is the code in my test app
StringEntity input = new StringEntity("{\"seriesid\ ":[\"LAUCN 0400100000 00005\", \"LAUCN040010000000006\"]} ");
input.setContentType("appl ication/js on");
postRequest.setEntity(inpu t);
input.setContentType("appl
postRequest.setEntity(inpu
Do I need to switch away from the WebClient Object and use the HttpWebRequest object to have this work?
Here is the code in my test app
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading.Tasks;
namespace Test
{
class Program
{
private static string BLSPublicDataS = "http://api.bls.gov/publicAPI/v1/timeseries/data/{0}";
private static string BLSPublicDataM = "http://api.bls.gov/publicAPI/v1/timeseries/data/";
//Single Series Signature
/// <summary>
/// Returns single series of data from the Bureau of Labor Statistics Web Site
/// </summary>
/// <param name="Series">Specific Series for which data is desired</param>
/// <returns>returns BSLData object populated with values returned</returns>
public static string GetBRSData(string Series)
//Debug Notes: This information provided in the API examples on the site
//Single Series
//HTTP Type: GET
//URL: http://api.bls.gov/publicAPI/v1/timeseries/data/<series_id>
//Payload: series_id
//Example Payload: LAUCN040010000000005
{
string serviceUrl = string.Format(BLSPublicDataS, Series);
// Synchronous Consumption
var syncClient = new WebClient();
syncClient.Headers["Content-type"] = "application/json";
var content = syncClient.DownloadString(serviceUrl);
var myBLSData = new ConsoleApplication1.BLSData();
//Console.Write(content.ToString());
//// Create the Json serializer and parse the response
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(ConsoleApplication1.BLSData));
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(content)))
{
myBLSData = (ConsoleApplication1.BLSData)serializer.ReadObject(ms);
}
return content.ToString();
}
//Clues from the BLS Site
//Apache HTTP Commons Client:
//The HttpPost HttpGet class can be used to connect to the BLS Public Data API via Apache HTTP Commons Client, as shown in the following example. Remember to include JSON as the ContentType.
// HttpPost httpPost = new HttpPost("http://api.bls.gov/publicAPI/v1/timeseries/data/");
//StringEntity input = new StringEntity("{\"seriesid\":[\"LAUCN040010000000005\", \"LAUCN040010000000006\"]}");
//input.setContentType("application/json");
//postRequest.setEntity(input);
//HttpResponse response = httpClient.execute(postRequest);
//variableFoo = response.getEntity().getContent()
// Multi Series Signature
/// <summary>
/// Returns multiple series of data from the Bureau of Labor Statistics Web Site
/// </summary>
/// <param name="Series">Multiple Series for which data is desired (up to 25) Series1,Series2 </param>
/// <returns>returns collection of BSLData objects populated with values returned</returns>
public static string GetBRSData(string Series1, string Series2)
//Use this signature to retrieve data for more than one timeseries for the past three years. You can include up to 25 series IDs, each //separated with a comma, in the body of your request.
//HTTP Type: POST
//URL: http://api.bls.gov/publicAPI/v1/timeseries/data/
//Payload: JSON Payload:
//{"seriesid":["Series1", ..., "SeriesN"]}
//Example Payload: {"seriesid":["LAUCN040010000000005", "LAUCN040010000000006"]}
{
//string inputData = string.Format("{\"seriesid\":[\"{0}\",\"{1}\"]}", Series1, Series2);
// DebugNote: The above does not generate the Payload exactly but then the below doesn't either.
// DebugNote: Learn more about quoting strings in a string. \" should work but it doesn't seam to.
//string inputPayload = "{\"seriesid\":[\"LAUCN040010000000005\", \"LAUCN040010000000006\"]}";
//Try this
string jsonPayload = "{" + "\"seriesid\":[" + "\"LAUCN040010000000005" + "\"," + "\"LAUCN040010000000006" + "\"]}";
// still get "{\"seriesid\":[\"LAUCN040010000000005\",\"LAUCN040010000000006\"]}"
string serviceUrl = BLSPublicDataM;
var syncClient = new WebClient();
syncClient.Headers["Content-type"]="application/json";
// I'm thinking something has to go here to add the inputPayload to the "Body" of the request.
<WHAT GOES HERE to include the jsonPayload string (once i fix it) with the request?>
var content = syncClient.DownloadString(serviceUrl);
Console.Write(content.ToString());
//// Create the Json serializer and parse the response
//DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(ConsoleApplication1.BLSData));
//using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(content)))
//{
// myBLSData = (ConsoleApplication1.WeatherData)serializer.ReadObject(ms);
//}
return content.ToString();
}
static void Main(string[] args)
{
Console.Write("Try a single request");
string test = GetBRSData("LAUCN040010000000005");
Console.Write(test);
Console.ReadKey();
Console.Write("Now the Multiple request");
string test2 = GetBRSData("LAUCN040010000000005","LAUCN040010000000006");
Console.WriteLine("End ");
}
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you, your solution works and enabled me to find the explanations I was looking for. The key learning for me was I was using download when upload was the correct choice.
I forgot to mention: I included the JSON.NET parser into the above code. Really it's up to you which parse you use so long as you turn your object into a string that you then pass to the GetBytes method. JSON.NET parser is a very simple to use library, though, IMO.