I am facing an exception while using Google translation API V2. Exception text is "The remote server returned an error: (403) Forbidden". Exception occurs when req.GetResponse()function called. I am using following code. Please mention if any correct code is available.
Thanks
public static string Translate()
{
String textToTranslate = "Common";
String fromLanguage = "en"; // english
String toLanguage = "ur"; // spanish
String apiKey = /*My API Key*/;
// create the url for making web request
String apiUrl = "https://www.googleapis.com/language/translate/v2?key={0}&source={1}&target={2}&q={3}";
String url = String.Format(apiUrl, apiKey, fromLanguage, toLanguage, textToTranslate);
string text = string.Empty;
try
{
// create the web request
WebRequest req = HttpWebRequest.Create(url);
// set the request method
req.Method = "GET";
// get the response
using (WebResponse res = req.GetResponse())
{
// read response stream
// you must specify the encoding as UTF8
// because google returns the response in UTF8 format
using (StreamReader sr = new StreamReader(res.GetResponseStream(), Encoding.UTF8))
{
// read text from response stream
text = sr.ReadToEnd();
}
}
}
catch (Exception e)
{
throw; // throw the exception as is/
}
// return text to callee
return text;
}
You either run into some Google-set API usage limit (see http://code.google.com/apis/language/translate/v2/getting_started.html)
OR
The problem lies in the language (ur = Urdu ?) you are using... you should check whether this combination is actually available via the respective API. If you really want spanish as your comment suggests I suspect that would be es.
Another point:
You are not escaping your URL parameters (esp. the text to be translated) which in turn could lead to some problems in the future...
Related
I have jobs in Jenkins that i cannot access unless i log in first using a my username and password.
For example if i try to access "localhost:xxx/job/some_job_1" i will get a 404 Error unless i log in first. And i say this because i have tried the following using WebRequest class:
string formParams = "j_username=bobbyLee&j_password=SecretPassword25&from=%2F&json=%7B%22j_username%22%3A+%bobbyLee%22%2C+%22j_password%22%3A+%22SecretPassword%25%22%2C+%22remember_me%22%3A+false%2C+%22from%22%3A+%22%2F%22%7D&Submit=log+in";
// ***this is the exact string that is sent when i log in normally, obtained using Fiddler***
string formUrl = "http://serverName:PortNum/j_acegi_security_check";
// ***I have also tried http://serverName:PortNum/login***
string cookieHeader;
WebRequest req = WebRequest.Create(formUrl);
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(formParams);
req.ContentLength = bytes.Length;
using (Stream os = req.GetRequestStream())
{
os.Write(bytes, 0, bytes.Length);
}
WebResponse resp = req.GetResponse();
cookieHeader = resp.Headers["Set-cookie"];
string pageSource;
string getUrl = "http://serverName:portNum/job/some_job/";
WebRequest getRequest = WebRequest.Create(getUrl);
getRequest.Headers.Add("Cookie", cookieHeader);
WebResponse getResponse = getRequest.GetResponse();
using (StreamReader sr = new StreamReader(getResponse.GetResponseStream()))
{
pageSource = sr.ReadToEnd();
}
The response that i get back from the POST request is "HTML OK", and cookieHeader is not null. But when i then try to make a GET request to get what i want, i get a 404 error when attempting to access the job "http://serverName:portNum/job/some_job/", as if i didn't log in successfully.
So what is the correct way to log into Jenkins from c#, and get the HTML source code of the jobs that only appears after logging in?
The RESTAPI is your best friend here.
It is an incredibly rich source of information. I have written a system that will show an entire program of work on a page with full deployment traceability.
I am going to assume you have some security in place in your Jenkins instance which means requests need to be authenticated.
I use the following class for this:
using System;
using System.Net;
using System.Text;
namespace Core.REST
{
public class HttpAdapter
{
private const string ApiToken = "3abcdefghijklmnopqrstuvwxyz12345"; // you will need to change this to the real value
private const string UserName = "restapi";
public string Get(string url)
{
try
{
const string credentials = UserName + ":" + ApiToken;
var authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials));
using (var wc = new WebClient())
{
wc.Headers[HttpRequestHeader.Authorization] = "Basic " + authorization;
var htmlResult = wc.DownloadString(string.Format(url));
return htmlResult;
}
}
catch (WebException e)
{
Console.WriteLine("Could not retrieve REST API response");
throw e;
}
}
}
}
restapi is a dedicated user I created. I think I gave it admin access just so I didn't have to worry about it. I was admin but all the other developers and testers in the 3 crews had highly controlled and limited access to only what they needed and nothing more. It is also better practice to have a dedicated users for functions like this.
I constructed my c# classes to consume (deserialise) data from any page that supports the api/json suffix.
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 successfully generated access_token for my website. I am able to retrieve all the required information, except one i.e., user_location. I tried to use the following two methods to retrieve location , but both return empty string.
Method-1
string access_tokens = tokens["access_token"];
var client = new FacebookClient(access_tokens);
dynamic me = client.Get("me");
string user_location me["user_location"].ToString();
Method-2
string user_location = GetUserLocation(fb_id);
//and here is the method
public static string GetUserLocation(string faceBookId)
{
WebResponse response = null;
string user_location = string.Empty;
try
{
WebRequest request = WebRequest.Create(string.Format("https://graph.facebook.com/{0}/user_location", faceBookId));
response = request.GetResponse();
user_location = response.ResponseUri.ToString();
}
catch (Exception e)
{
//catch exception
}
finally
{
if (response != null) response.Close();
}
return user_location;
}
Location is actually received when I try to debug in the Graph API Explorer at developer.facebook.com ! When I put the parameter location - the location is received as expected.
Alternately I also tried to change the request URL with this :
WebRequest request = WebRequest.Create(string.Format("https://graph.facebook.com/{0}/location", faceBookId));
Why is this happening ?
There is no /user-ID/user_location edge in Facebook's Graph API.
There is a location field on the /user-ID object.
user_location is the name of the OAuth permission scope that you need to obtain in order to be able to read that field. See also: FB docs.
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.
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);