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.
Related
I'm trying to get the order book from GDAX (link to documentation of the call) but when doing it from the c# executable I always get Error 400 - Bad request.
When taking the actual URL and pasting it into my browser, it works fine.
String URL = "https://api.gdax.com/products/BTC-USD/book?level=2";
WebRequest request = WebRequest.Create(URL);
WebResponse response = request.GetResponse();
The actual issue with your API call is , the API is expecting a user-agent string while making the request: Below is the code in working condition:
try
{
String URL = "http://api.gdax.com/products/BTC-USD/book?level=2";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.UserAgent = ".NET Framework Test Client";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
var encoding = ASCIIEncoding.ASCII;
using (var reader = new System.IO.StreamReader(response.GetResponseStream(), encoding))
{
string responseText = reader.ReadToEnd();
}
}
catch(WebException ex)
{
HttpWebResponse xyz = ex.Response as HttpWebResponse;
var encoding = ASCIIEncoding.ASCII;
using (var reader = new System.IO.StreamReader(xyz.GetResponseStream(), encoding))
{
string responseText = reader.ReadToEnd();
}
}
Basically ProtocolError indicates that you have received the response but there is an error related to protocol, which you can observe, when you read the response content from exception. I have added catch to handle the exception and read ex.Response (which is HttpWebResponse) and could see that the API is asking for user-agent to be suppllied while making the call. I got to see the error as "{"message":"User-Agent header is required."}"
You can ignore the code inside the exception block, I used it only to see what is the actual response message, which contains actual error details
Note: I have boxed WebRequest to HttpWebRequest to have additional http protocol related properties and most importantly "UserAgent" property which is not available with the WebRequest class.
You need to Accept the certificarte, Google for access to a https webrequest.
Like this
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.
I have one Windows Handheld device application on .Net framework 3.5 which has the requirement of accessing a REST API. The REST API gives me JSON output which I am going to process later. I have the following code for that:-
HttpWebRequest webRequest;
string result = String.Empty;
try
{
webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Method = "POST";
webRequest.KeepAlive = false;
webRequest.ContentType = "application/x-www-form-urlencoded";
using (WebResponse response = webRequest.GetResponse())
{
using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
}
}
catch (Exception ex)
{
result = ex.Message;
}
The url variable is holding the url for the API with some query parameters in it.
For Example "http://www.something.com/Login?id=test&pwd=test".
Now my problem is I dont want to use the query string parameters rather I want to use Request parameters because the above approach does not work every time perfectly. Some times I get an "Unauthorized" error. And also I have one tokenId which I need to send everytime I am calling the API and the token Id is in base64 format.
Can anyone please help me how can I use the Request Parameter feature to send the parameter values?
use the Headers property of your request object.
webRequest.Headers.Add("id", "test");
webRequest.Headers.Add("pwd", "test");
webRequest.Headers.Add("token", myToken);
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
}
I am encountering an unusually strange behavior when POSTing a Json string to a PHP webserver. I use the JsonTextWriter object to create the Json string. I then send the Json string as a POST request. Please see comments. The HTML response in the code is returning the correct output, but when viewed in a browser, the web page displays either NULL or array(0) { }.
private void HttpPost(string uri, string parameters)
{
WebRequest webRequest = WebRequest.Create(uri);
webRequest.ContentType = "application/x-www-form-urlencoded"; // <- Should this be "application/json" ?
webRequest.Method = "POST";
byte[] bytes = Encoding.UTF8.GetBytes(parameters);
string byteString = Encoding.UTF8.GetString(bytes);
Stream os = null;
try
{ // Send the Post Data
webRequest.ContentLength = bytes.Length;
os = webRequest.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
Console.WriteLine(String.Format(#"{0}", byteString)); // <- This matches the Json object
}
catch (WebException ex)
{ //Handle Error }
try
{ // Get the response
WebResponse webResponse = webRequest.GetResponse();
if (webResponse == null) { return null; }
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
Console.WriteLine(sr.ReadToEnd().Trim()); // <- Server returns string response (full HTML page)
}
catch (WebException ex)
{ //Handle Error }
}
Relevant PHP code on the server:
$json = json_encode($_POST); # Not 'standard way'
var_dump(json_decode($json));
Any suggestions would be greatly appreciated.
Thanks
Try using "application/json" as the content type. Also, check the request logs or maybe do a port 80 trace if you can to view what's being sent to the server in the request body.
You can also narrow the scope of the problem -- is it the C# code or the PHP code that's bad -- by writing a quick JQuery ajax function that sends some JSON to the PHP server. This isolation of the PHP code from the C# code will tell you if the PHP is at least working correctly. If it is, then the problem is in the C# code.