I am getting 401 access error when running the below code. Can someone please tell me what I am doing wrong. thanks
The Curl provided is: curl -X GET --header "Authorization: " --header "Authorization: Bearer kgffj*dfkgj40fdgjkjkdfjUHHHDNhdfj" "https://api.united.com/v1/accounts"
string url = "https://api.united.com/v1/accounts";
WebRequest myReq = WebRequest.Create(url);
string credentials = "kgffj*dfkgj40fdgjkjkdfjUHHHDNhdfj";
CredentialCache mycache = new CredentialCache();
myReq.Headers["Authorization"] = "Bearer " + Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials));
WebResponse wr = myReq.GetResponse();
Stream receiveStream = wr.GetResponseStream();
StreamReader reader = new StreamReader(receiveStream, Encoding.UTF8);
string content = reader.ReadToEnd();
Console.WriteLine(content);
var json = "[" + content + "]"; // change this to array
var objects = JArray.Parse(json); // parse as array
foreach (JObject o in objects.Children<JObject>())
{
foreach (JProperty p in o.Properties())
{
string name = p.Name;
string value = p.Value.ToString();
Console.Write(name + ": " + value);
}
}
Console.ReadLine();
The curl request would be represented like this in C#
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("GET"), "https://api.united.com/v1/accounts"))
{
request.Headers.TryAddWithoutValidation("Authorization", "Bearer kgffj*dfkgj40fdgjkjkdfjUHHHDNhdfj");
var response = await httpClient.SendAsync(request);
}
}
I could not test this code as the url https://api.united.com/v1/accounts times out from my system. But This should work.
As others have pointed out you should not need to convert the token to base 64 as its not converted to base64 in the curl
I am assuming that you want to perform the same request that you would run if you use the curl command in your question
The code provided above fixes the http request.
The response object in the above code is of Type HttpResponseMessage
This object has a HttpResponseMessage.Content Property on it
This Content is of type HttpContent and it has a public method ReadAsStringAsync() which will
Serialize the HTTP content to a string as an asynchronous operation.
and that is your JSON content that you are looking for.
So your code should look like this
public static async Task<string> GetData()
{
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("GET"), "https://api.united.com/v1/accounts"))
{
request.Headers.TryAddWithoutValidation("Authorization", "Bearer kgffj*dfkgj40fdgjkjkdfjUHHHDNhdfj");
var response = await httpClient.SendAsync(request);
return await response.Content.ReadAsStringAsync();
}
}
}
This method is an async method,Since the code you provided in the question is not async you would need to use
string json = GetData().Result;
if you want to use it in a non async function
or if you change your method calling this method to async then you can use the await keyword like this
string json = await GetData();
It is unlikely you can just hardcode an OAuth Bearer token. You need to lookup the details for authentication for that specific API to see how to obtain a Bearer token for use in the API.
Related
I'm consuming a Web API of an internal system in the company.
It's getting a payload in JSON format and returning a response with data in JSON format.
When sending the request with Postman, it returns the expected response (StatusCode=200 + a response text in JSON format). That means that everything is OK with the web service.
Now I have to develop an application in C# to send this HTTP request.
The problem is, that I receive as response content "OK" and not the expected JSON response gotten with Postman.
public HttpWebResponse SendRequest(string url, string checkOutFolder, string drawingNo, string login, string password)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "application/json";
request.Method = "GET";
request.Accept = "application/json";
string payload = GeneratePayLoad(checkOutFolder, drawingNo);
string header = CreateAuthorization(login, password);
request.Headers[HttpRequestHeader.Authorization] = header;
request.ServicePoint.Expect100Continue = false;
var type = request.GetType();
var currentMethod = type.GetProperty("CurrentMethod", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(request);
var methodType = currentMethod.GetType();
methodType.GetField("ContentBodyNotAllowed", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(currentMethod, false);
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(payload);
}
// Response
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader rd = new StreamReader(response.GetResponseStream()))
{
string responseContent = rd.ReadToEnd();
Console.WriteLine(responseContent);
}
return response;
}
Has anyone already experiences something similar.
Can you help me?
EDIT
Following your suggestions
1) Changed the method to POST -> result is still the same
2) Used Postman's code generator and RestSharp -> result is still the same
public void Request(string url, string checkOutFolder, string drawingNo, string login, string password)
{
var client = new RestClient(url);
var request = new RestRequest();
request.Method = Method.Post;
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", "Basic **********");
var body = GeneratePayLoad(checkOutFolder, drawingNo);
request.AddParameter("application/json", body, ParameterType.RequestBody);
var response = client.Execute(request);
Console.WriteLine(response.Content);
}
Changed to HttpClient -> result still the same
using (var client = new HttpClient())
{
string uri = "******************";
string path = "destinationpath";
var endpoint = new Uri(uri);
string payload = GeneratePayLoad(path, "100-0000947591");
//FormUrlEncodedContent form = new FormUrlEncodedContent(payload);
var stringContent = new StringContent(payload);
var payload2 = new StringContent(payload, Encoding.UTF8, "application/json");
var byteArray = Encoding.ASCII.GetBytes("*******");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
var base64EncodedAuthenticationString = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(client.DefaultRequestHeaders.Authorization.ToString()));
var result = client.PostAsync(endpoint, stringContent).Result.Content.ReadAsStringAsync().Result;
Console.WriteLine("test");
}
Wrote a Python code using requests Package -> delivers the same as Postman. So the problem is in the C# code.
Does anyone have an idea what is going on?
SOLVED
The issue was on the payload generation!
The request needs to be an HTTP POST and not HTTP GET because it contains JSON payload.
request.Method = "GET"; should be request.Method = "POST";
That would be one of the issue(s). I am not sure if there is something else that is wrong, but try changing the request method to POST and try again.
I've got a section of code to do a call to an external webapi using WebRequest. I'm trying to update it to use RestSharp instead. What am I missing here to make the conversion? The closest question here to give any sort of idea what might be going on is found in Calling webapi method gives 404. The "answer" was a missing accepted content type. I've verified through the RestClient the types are present (and appear valid).
Common request JSON
var statusRequest = #"
{
""auth"": {
""type"": ""basic""
},
""requestId"": ""15"",
""method"": {
""name"": ""getStatus"",
""params"": {
""showAllStatus"": ""0""
}
}
}
";
WebRequest code
var webRequest = WebRequest.Create("https://service.url/api/status") as HttpWebRequest;
webRequest.Method = "POST";
var username = "user";
var password = "pass";
var encoded = System.Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1")
.GetBytes(username + ":" + password));
webRequest.Headers.Add("Authorization", "Basic " + encoded);
var requestWriter = new StreamWriter(webRequest.GetRequestStream());
webRequest.ContentType = "APPLICATION/JSON; CHARSET=UTF-8";
requestWriter.Write(statusRequest);
requestWriter.Close();
var responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream());
var responseData = responseReader.ReadToEnd();
responseReader.Close();
Should convert to RestSharp as
var client = new RestClient("https://service.url");
client.Authenticator = new HttpBasicAuthenticator("user", "pass");
var request = new RestRequest("api/status", Method.Post);
request.RequestFormat = DataFormat.Json;
request.AddJsonBody(statusRequest);
client.BuildUri(request);
var response = await client.GetAsync(request);
EDIT: Make the RestRequest a POST
Please read the docs.
Also, you are calling GetAsync. Even if you set the request method to Method.Post, calling GetAsync will override it.
This will work:
var request = new RestRequest("api/status")
.AddStringBody(statusRequest, DataFormat.Json);
var response = await client.PostAsync(request);
I am trying to POST to using C# to a JSON payload which I can achieve but I am having trouble understanding how to replace the sample string with my own string.
From the code below you can see I have a string I want to send to my weblink. The code runs fine when I use "{\"text\":\"Hello, World!\"}" for the StringContent but if I try to replace it with the string of output_message it doesn't work. I am trying to work out how I convert my output_message to a format that JSON can recognize.
{
string output_message = "The file " + filename + " has been modified by " + user_modified + " and moved to the " + file_state + " file state. Please review the " + filename + " file and approve or reject.";
PostWebHookAsync(output_message);
Console.ReadLine();
}
static async void PostWebHookAsync(string Aoutput_message)
{
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "www.mywebsitelink"))
{
//request.Content = new StringContent("{\"text\":\"Hello, World!\"}", Encoding.UTF8, "application/json"); // - original do not delete
request.Content = new StringContent(Aoutput_message, Encoding.UTF8, "application/json");
var response = await httpClient.SendAsync(request);
Console.WriteLine(response.StatusCode);
Console.WriteLine(response.Content);
}
}
}
I want to replace "{\"text\":\"Hello, World!\"}" with a string
To the best of my knowledge people are moving away from JavaScriptSerializer and towards Json.NET. It's even recommended in the documentation here
The corresponding Json.NET code would look something like:
static async void PostWebHookAsync(string output_message)
{
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "www.mywebsitelink"))
{
string jsonValue = JsonConvert.SerializeObject(new
{
text = output_message
});
request.Content = new StringContent(jsonValue, Encoding.UTF8, "application/json");
var response = await httpClient.SendAsync(request);
Console.WriteLine(response.StatusCode);
Console.WriteLine(response.Content);
}
}
}
To use Json.NET you need to install the Newtonsoft.Json nuget package.
The best way is to create an object and serialize it.
To use JavaScriptSerializer you have to add a reference to System.Web.Extensions.dll
So for your problem, we create an anonymous object with a property text we pass the value Aoutput_message
static async void PostWebHookAsync(string Aoutput_message)
{
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "www.mywebsitelink"))
{
//request.Content = new StringContent("{\"text\":\"Hello, World!\"}", Encoding.UTF8, "application/json"); // - original do not delete
string jsonValue = new JavaScriptSerializer().Serialize(new
{
text = Aoutput_message,
});
request.Content = new StringContent(jsonValue, Encoding.UTF8, "application/json");
var response = await httpClient.SendAsync(request);
Console.WriteLine(response.StatusCode);
Console.WriteLine(response.Content);
}
}
}
Examples
Well Im new in Xamarin and I'm developing and App, the authentication is JWT based.
Im using a HttpClient and setting the AuthenticationHeaders but It always returns Unauthorized when I try it on Postman it Works but I can't make it work in my app.
Here is how im trying to do it:
var client = new HttpClient(new HttpClientHandler());
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("JWT", accessToken);
client.BaseAddress = new Uri(urlBase);
var url = string.Format("{0}{1}", servicePrefix, controller);
var response = await client.GetAsync(url);
Try something like this
using (var client = new HttpClient())
{
var uri = new Uri(string.Format($"{<yourURLString>}", string.Empty));
var jsonTransport = "";
var jsonPayload = new StringContent(jsonTransport, Encoding.UTF8, "application/json");
//client.DefaultRequestHeaders.Add("Content-type", "application/json");
client.DefaultRequestHeaders.Add("Authorization", "JWT " + accessToken);
var response = await client.PostAsync(uri, jsonPayload);
string responseContent = await response.Content.ReadAsStringAsync();
}
then deserialize the responseContent to your object using JsonConvert.DeserializeObject
Note: Below are code samples, edit to your own objects
SubscriptionResponse profileResponse = JsonConvert.DeserializeObject<SubscriptionResponse>(responseContent);
then if your method returns something, use the return statement. Something like this
return profileResponse.Data.Subscriptions;
If you're using a get, this could be a guide
var uri = new Uri(string.Format($"{<yourURLHere>}", string.Empty));
client.DefaultRequestHeaders.Add("Authorization", "JWT " + accessToken);
var httpResponse = await client.GetAsync(uri);
var responseContent = await httpResponse.Content.ReadAsStringAsync();
then deserialize your string response
Note: this is a sample - edit to your model (You may use PostMan to get the response format in JSON and model it in C#)
var UserDetailResponse = JsonConvert.DeserializeObject<UserDetail>(responseContent);
return UserDetailResponse;
I'm trying to use HttpClient to POST a new Account via SalesForce RESTApi, but I'm receiving the following error:
message: "Can not deserialize SObject out of VALUE_STRING token at [line:1, column:1]".
errorCode: "JSON_PARSE_ERROR".
I'm using the same json for WebRequest and HttpClient tests. With WebRequest, it works well.
Here is my code with HttpClient:
var uri = "https://na15.salesforce.com/services/data/v27.0/sobjects/Account";
var acc = new Account();
acc.Name = "RestAPIHttpClient";
var ser = new JavaScriptSerializer();
var json = ser.Serialize(acc);
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + binding.SessionHeaderValue.sessionId);
var response = await client.PostAsJsonAsync(uri, json);
var stringresponse = await response.Content.ReadAsStringAsync();
Console.WriteLine(stringresponse);
The account class that im serializing is just that simple:
private class Account
{
public string Name { get; set; }
}
UPDATE:
I changed the code to use PostAsync besides PostAsJsonAsync, then i added the JsonFormatter at the Content and now it is working. Would be great to know why PostAsJsonAsync doesn't work.
System.Net.Http.Formatting.MediaTypeFormatter jsonFormatter =
new System.Net.Http.Formatting.JsonMediaTypeFormatter();
System.Net.Http.HttpContent content =
new System.Net.Http.ObjectContent<Account>(acc, jsonFormatter);
var response = await client.PostAsync(uri, content);