LearnUPON - I'm getting 404 response when call my Insert API - c#

I'm going to implement Learn Upon API into my .NET MVC application, they gave cURL and I have to convert these cURL URL into the web request in C# for getting or sending data to the third party Learn Upon API server thing is that Listing API, Delete API was working fine but Create & Update API always returns The remote server returned an error: (404) Not Found.
cURL sample given by Learn Upon:
curl -X POST -H "Content-Type: application/json" --user 988d4f1313f881e5ac6bfdfc7f54244aab : 905a12r3a0c -d '{"User": {"last_name" : "Upon",
"first_name" : "Learn", "email" : "learnuponapi#samplelearningco.com", "password" : "password1", "language" : "en", "membership_type" : "Member"
}}' https://yourdomain.learnupon.com/api/v1/users
As per above cURL, I have written below web request call for API calls, and this pattern worked in Listing/Delete API.
POST Model:
{
"first_name": "Krishna",
"last_name": "Patel",
"email": "krishna.patel#test.com",
"password": "1234567890",
"language": "en",
"membership_type": "Member",
"username":"krishna.patel"
}
Create API Code:
[System.Web.Http.HttpPost]
public IHttpActionResult CreateUser(UserModel mdlUser)
{
string content = "";
try
{
if (ModelState.IsValid)
{
// target url given by Learn Upon, Unique for each account
string yourTarget = "https://{domain}/api/v1/users";
string josnUserModel = JsonConvert.SerializeObject(mdlUser);
josnUserModel = "{\"User\":" + josnUserModel + "}";
WebRequest yourWebRequest = WebRequest.Create(yourTarget);
yourWebRequest.Method = "POST";
// Establish credentials (if necessary)
CredentialCache yourCredentials = new CredentialCache();
yourCredentials.Add(new Uri(yourTarget), "Basic", new NetworkCredential(username, password));
// Set your credentials for your request
yourWebRequest.Credentials = yourCredentials;
// Add basic authentication headers (if necessary)
yourWebRequest.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(new ASCIIEncoding().GetBytes(String.Format("{0}:{1}", username, password))));
yourWebRequest.Headers.Add("data", josnUserModel);
WebResponse yourWebResponse = yourWebRequest.GetResponse();
string s = yourWebResponse.ToString();
// Get your response stream
using (var reponseStream = yourWebResponse.GetResponseStream())
{
// Build a reader to read your stream
using (var responseReader = new StreamReader(reponseStream, Encoding.UTF8))
{
// Get your result here
content = responseReader.ReadToEnd();
JObject json = JObject.Parse(content);
return Ok(json);
}
}
}
else
{
return ResponseMessage(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState));
}
}
catch (Exception ex)
{
return ResponseMessage(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message));
}
}
API Returns:
{
"Message": "The remote server returned an error: (404) Not Found."
}
Note: Above message comes from the exception catch block, every time exception occurs and return 404 response.

Are you sending any data in the POST request body?
It looks to me, as someone with very little C# experience, as if you're sending the mdlUser data as a HTTP Request Header (called data), and not sending anything in the POST body. There are a few examples of making a POST request in this question: How to make HTTP POST web request
That's likely to be the 404 problem (or, at least, the first one!). The exception you're catching is a legitimate exception (4xx is mostly considered an non-normal state). If you want to capture a 404 (which can be a legitimate response for the LearnUpon API when, for example, checking if a user exists in your portal), look at this question: How can I catch a 404?
Finally, feel free to reach out to your LearnUpon support team. We might not have all the answers a developer needs, but we can normally point you in the right direction.
Disclaimer: I work with LearnUpon.

Related

name, given_name and family_name json property are missing in google + api get user info

I have created google api services app and verify that user.profile info scope is by default added.
Authentication, token and get the user info is working fine for me, however few fields are missing in get user info api response.
I am using below mentioned endpoints to communicate with google api.
Authentication : https://accounts.google.com/o/oauth2/v2/auth
Retrieving Token : https://accounts.google.com/o/oauth2/token
Getting User Info : https://www.googleapis.com/oauth2/v2/userinfo?access_token=xxxxxxxxxx and https://www.googleapis.com/oauth2/v1/userinfo?access_token=xxxxxxxxxx
WebRequest request = WebRequest.Create(googleGetUrl + $"&access_token={accesstoken}");
request.Credentials = CredentialCache.DefaultCredentials;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream receiveStream = response.GetResponseStream())
{
using (StreamReader readStream = new StreamReader(receiveStream))
{
string responseFromServer = readStream.ReadToEnd();
return JsonConvert.DeserializeObject<GoogleUser>(responseFromServer);
}
}
}
I am getting the json response as mentioned below
{
id: "xxxxxxxxxxxxx",
email: "dummy#email.com",
verified_email: true,
picture: "https://validurl/photo.jpg",
hd: "getting value"
}
But what I want expect like below mentioned Json
{
id: "xxxxxxxxxxxxx",
email: "dummy#email.com",
verified_email: true,
picture: "https://validurl/photo.jpg",
hd: "getting value",
name: "some value",
family_name: "some value",
given_name: "some value"
}
scope configuration :
enter image description here
Please let me know if I have missed any configuration. Your help would be much appreciated.
Kind Regards,
Mohsin
I was missing scope parameter in authentication URL and having used below URL works for me.
return string.Format(
"https://accounts.google.com/o/oauth2/auth?client_id={0}&redirect_uri={1}&response_type=code&scope={2}",
ClientId,
CallBackUrl,
"https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email");
The response from the userinfo endpoint is not standards all oauth servers have their own implementation of what they will return. If you want to get more information you should try the people api. No one should return email unless you request the email scope. And google stopped returning verified_email a few years ago i think.
GET /v1/people/me HTTP/1.1
Host: people.googleapis.com
Content-length: 0
Authorization: Bearer aJxKQvzgCj5fa86EbB_AYqjt-

RestSharp http statut code and response statut of 0 "Error: SecureChannelFailure (The authentication or decryption has failed.)"

I'm trying to query data on my mlab mongodb database with their rest api but I can't get it to work.
To makehttp rest requests in my Xamarin application I'm using restSharp, I tried many times but I always get an empty answer, not event the header so I really don't know where the problem is coming from.
Here is my code:
class HttpDataHandler
{
static String stream = null;
public String GetHttpData(String collection)
{
var uri = "https://api.mlab.com";
var client = new RestClient(uri);
var request = new RestRequest("api/1/databases/{db}/collections/{coll}" , Method.GET);
request.AddParameter("apiKey", Common.API_KEY); // adds to POST or URL querystring based on Method
request.AddUrlSegment("db", Common.DB_NAME);
request.AddUrlSegment("coll", collection);
IRestResponse response = client.Execute(request);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
System.Console.WriteLine(response.Content); // raw content as string
else
System.Console.WriteLine(response.StatusDescription + " " + response.ResponseUri+" "+ response.StatusCode);
return stream;
}
}
mLab is using TLS1.2. Changing the SSL/TLS implementation of your Android project from Default to Native TLS 1.2+ most likely will fix the issue.
See the HttpClient Stack and SSL/TLS documentation for an extensive explanation on these 2 combo-boxes that are provided in Xamarin Android projects.

LinkedIn API failed to connect when trying to get companies informations

When I try to get profile information, using HttpWebRequest, it works perfectly, it returns the response I need.
But when I try to get company informations, the LinkedIn web service returns the following error.
{ "errorCode": 0,
"message": "Unknown authentication scheme",
"requestId": [RequestID],
"status": 401,
"timestamp": 1479383163405 }
I used the same access token in both queries. And I can't figure why I have a failed authentication in the second query.
There are the 2 functions :
//Get profile :
private void GetPeopleProfile(string accessToken) {
var peopleUrl = String.Format("https://api.linkedin.com/v1/people/~?oauth2_access_token={0}&format=json",accessToken);
HttpWebRequest webRequest = WebRequest.Create(peopleUrl) as HttpWebRequest;
StreamReader responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream());
string responseData = responseReader.ReadToEnd();
JObject updates = JObject.Parse(responseData);
responseReader.Close();
webRequest.GetResponse().Close();
}
//Get profile's Company :
private void GetUserCompanies(string accessToken){
var copaniesUrl = String.Format("https://api.linkedin.com/v1/companies?format=json&is-company-admin=true?oauth2_access_token={0}&format=json", accessToken);
HttpWebRequest webRequest = WebRequest.Create(copaniesUrl) as HttpWebRequest;
StreamReader responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream());
string responseData = responseReader.ReadToEnd();
JObject updates = JObject.Parse(responseData);
responseReader.Close();
webRequest.GetResponse().Close();
}
Maybe wrong URL?
Parameters separators are wrong here (two ? in a URL seems wrong, you are also repeating format=json) :
"https://api.linkedin.com/v1/companies?format=json&is-company-admin=true?oauth2_access_token={0}&format=json"
This looks better:
"https://api.linkedin.com/v1/companies?format=json&is-company-admin=true&oauth2_access_token={0}"
You can try the REST api here without your code noise.
It seems that the Linkedin API now expects an authorization HTTP header instead of a querystring parameter oauth2_access_token.
This is accomplished by including an "Authorization" header in your HTTP call to LinkedIn's API.
https://developer.linkedin.com/docs/oauth2
Try this and remove the access token from the querystring:
webRequest Headers.Add("Authorization", "Bearer " + accessToken);

C# Asana POST new task returns error 400 (Bad request)

I have a problem with creating new task in Asana from my app.
Post method:
protected static T Post<T>(string route, object action = null, object parameters = null) where T : BaseResult, new()
{
var result = new T();
try
{
var actionUrl = GetActionUrl(route, action);
var request = (HttpWebRequest)WebRequest.Create(actionUrl);
request.Credentials = CredentialCache.DefaultCredentials;
request.Accept = "application/json";
request.Method = WebRequestMethods.Http.Post;
request.Proxy.Credentials = CredentialCache.DefaultCredentials;
request.Headers.Add("Authorization: Bearer " + ApiKey);
if (parameters != null)
{
var contentJSON = JsonConvert.SerializeObject(parameters);
request.ContentType = "application/json";
using (var s = request.GetRequestStream())
using (var sw = new StreamWriter(s, Encoding.UTF8))
sw.Write(contentJSON);
}
var response = (HttpWebResponse) request.GetResponse();
using (var reader = new StreamReader(response.GetResponseStream()))
{
var data = reader.ReadToEnd();
result = JsonConvert.DeserializeObject<T>(data);
}
}
catch (Exception ex)
{
result.IsOk = false;
result.Message = ex.GetMessage();
}
return result;
}
Action URL: https://app.asana.com/api/1.0/workspaces/MyWorkspace/tasks
JSON:{"data":{"name":"TestTask1","notes":"Test note","workspace":"*MyWorkspace*","assignee":"*MyAssignee"}}
But Asana returns me "The remote server returned an error: (400) Bad Request."
If I change request.ContentType to "application/x-www-form-urlencoded", I get no errors, but Asana returns me new task with empty fields.
What my next steps to fix issue should be?
Thank you
If you're using an ApiKey (and not a Personal Access Token), I believe that your Authorization Header should be
"Authorization: Basic " + EncodedAuthInfo
where
EncodedAuthInfo = Convert.ToBase64String(Encoding.Default.GetBytes(ApiKey + ":"))
See How do I connect to the Asana Rest API using c#? or the Using Basic Authentication section in https://asana.com/developers/documentation/getting-started/auth for details on using basic authentication.
I'm also a little confused by what you mean when you say that
JSON = {"data": {"name": "TestTask1"} ...
Is this the HTTP response that you expect?
Anyways, hopefully what I've outlined helps.
Hmm. I think I've got what's blocking you sorted out.
Imagine the scenario where you post to
https://app.asana.com/api/1.0/workspaces/123456/tasks
and you pass in the request body the parameter
"workspace":"789012"
What should the Asana platform do with this data? You've inadvertently specified the workspace twice with conflicting numbers. For this reason, you cannot specify the workspace id in the data when hitting an endpoint which also contains the workspace id in the URL.
The documentation is confusing on this point, because we don't clarify which parameters are found in the URL and which parameters are found in the JSON in the request body. I'm actually fixing this very soon! If this is indeed what's causing the issue, I'm sorry that we were not clear on this.
Personally, I think it might be a better user experience to allow the workspace to be duplicated in the parameter data if and only if it's identical to the one in the URL, but right now, we simply check to see that there is only one value for the workspace id. If there are more than one, even if they are the same one, we return the 400 error code.
You might consider parsing the response body, even on errors. In it, we try to provide fairly decent information about what was wrong about the request. For example, when testing my hunch about your request, what I got back was:
"errors":[{"message":"Duplicate field: workspace", ...}]
If we've done a good job about sending back informative messages, I hope you'll find this even more useful than an Asana sandbox! If this is not the issue, feel free to comment; I'll be happy to dive into this further.

Trouble with HTTP post in Android

I am fairly new at android development. Here is my problem:
I have this endpoint: http://bdzservice.apphb.com/api/Image which accepts POST requests
The body of the request is a String, example:
/SearchServlet?action=showMap&id1=25&date=09/12/2013&st1=5216000&st2=5229030
Invalid example: {"/SearchServlet?action=showMap&id1=25&date=09/12/2013&st1=5216000&st2=5229030"}
Invalid example2: {mapHref : "/SearchServlet?action=showMap&id1=25&date=09/12/2013&st1=5216000&st2=5229030"}
Invalid example3: {"mapHref" : "/SearchServlet?action=showMap&id1=25&date=09/12/2013&st1=5216000&st2=5229030"}
this is the code I've written so far:
HttpClient client = new DefaultHttpClient();
String message;
HttpPost httpPost = new HttpPost("http://bdzservice.apphb.com/api/Image");
try
{
message = url;
StringEntity se = new StringEntity(message, "UTF8");
se.setContentType("application/json");
httpPost.setEntity(se);
httpPost.setHeader("Content-type", "application/json");
HttpResponse resp = client.execute(httpPost);
if (resp != null)
{
if (resp.getStatusLine().getStatusCode() == 204)
result = true;
}
Log.d("Status line", "" + resp.getStatusLine().getStatusCode());
}
I always get an error when trying to post data, but when I manually (through a REST client) post data I get an OK result.
Can someone help me with this?
EDIT
This is the endpoint, It is written in C# (Web Api)
EDIT 2: Tried modifying the service to return body it recieved (see the comment in the url) and it retruns null, so the problem is it is not getting the body (or just reading it wrong)
I have created a library here for .NET Standard that does POST and PUT. I have tested it thoroughly on Android. There are quick start samples to get going quickly. The sample only has a PUT, but the principle should be the same:
https://bitbucket.org/MelbourneDeveloper/restclient-.net/overview

Categories

Resources