Posting JSON to REST Service - c#

I am attempting to consume a Data source from Plex a cloud ERP System with Rest. I am receiving a forbidden status code upon sending the PUT
public static string Put(string url,string Body,PCNModel pcn)
{
HttpClient client = new HttpClient();
int timeOutSec = 90;
string accept = "application/json";
string acceptEncoding = "gzip, deflate";
string contentType = "application/json";
var credentials = pcn.UserName + ":" + pcn.Password;
var bytes = Encoding.UTF8.GetBytes(credentials);
var encodedCredentials = Convert.ToBase64String(bytes);
var authorizationHeaderValue = encodedCredentials;
HttpResponseMessage response = new HttpResponseMessage();
client.Timeout = new TimeSpan(0, 0, timeOutSec);
//client.DefaultRequestHeaders.Add("Accept", string.Format(accept));
client.DefaultRequestHeaders.Add("Accept", (accept));
client.DefaultRequestHeaders.Add("Accept-Encoding", string.Format(acceptEncoding));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(contentType));
client.DefaultRequestHeaders.Add("Authorization", string.Format("Basic {0}", authorizationHeaderValue));
HttpContent httpBody = Body;
httpBody.Headers.ContentType = new MediaTypeHeaderValue(contentType);
response = client.PutAsync(url, httpBody).Result;
var error = response.StatusCode.ToString();
var requestMessage = response.RequestMessage;
var responseContent = response.Content;
var responseReasonPhrase = response.ReasonPhrase;
var responseHeader = response.Headers;
MessageBox.Show(error);
MessageBox.Show(requestMessage.ToString());
//MessageBox.Show(responseContent.ToString());
//MessageBox.Show(responseReasonPhrase.ToString());
//MessageBox.Show(responseHeader.ToString());
var content = response.Content.ReadAsStringAsync().Result;
return content;
}
I am not sure where it is bouncing back at me.

You need to parse body to json before calling PutAsync here is a small code sinppet
client.DefaultRequestHeaders.Add("authKey", authKey);
var json = JsonConvert.SerializeObject(product, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PutAsync(url, content);
if (response.IsSuccessStatusCode)
{
}
else
{
var result = response.Content.ReadAsStringAsync().Result;
throw new Exception("Error Occured in Update Product" + result);
}

It turns out that the credentials I was provided were incorrect. Which prevented me from processing web services calls to the endpoint.

Related

RestSharp to HttpClient

var client = new RestClient("http://10.0.0.244:8885/terminal/info");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("apikey", "adasdsadasd");
var body = #"{}";
request.AddParameter("application/json", body, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
Could someone, please, help me write this code with HttpClient?
I try following code.
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://10.0.0.244:8885/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Clear();
HttpRequestMessage request = new HttpRequestMessage();
request.Method = HttpMethod.Post;
request.RequestUri = new Uri($"{client.BaseAddress}/terminal/info");
request.Headers.Add("apikey", "adasdsadasd");
var body = Newtonsoft.Json.JsonConvert.SerializeObject(new { });
request.Content = new StringContent(body, Encoding.UTF8, "application/json");//CONTENT-TYPE header
request.Content.Headers.Clear();
request.Content.Headers.ContentLength = 2;
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.SendAsync(request).GetAwaiter().GetResult();
var x = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
}
But it response with Status Code 400 (ParseError)
You can accomplish what you are trying to do with much less code. Also this should be in an async method. Below is an example
internal async Task<string> GetResponse()
{
using var client = new HttpClient();
client.BaseAddress = new Uri("http://10.0.0.244:8885/");
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("apikey", "adasdsadasd");
var content = new StringContent("{}", Encoding.UTF8, "text/plain");
var response = await client.PostAsync("/terminal/info", content);
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync();
}
return null;
}

Send JSON data in http post request C#

I'm trying to send a http post request in JSON format which should look like this:
{
"id":"72832",
"name":"John"
}
I have attempted to do it like below but if I am correct this is not sending a request in json format.
var values = new Dictionary<string,string>
{
{"id","72832"},
{"name","John"}
};
using (HttpClient client = new HttpClient())
{
var content = new FormUrlEncodedContent(values);
HttpResponseMessage response = await client.PostAsync("https://myurl",content);
// code to do something with response
}
How could I modify the code to send the request in json format?
try this
using (var client = new HttpClient())
{
var contentType = new MediaTypeWithQualityHeaderValue("application/json");
var baseAddress = "https://....";
var api = "/controller/action";
client.BaseAddress = new Uri(baseAddress);
client.DefaultRequestHeaders.Accept.Add(contentType);
var data = new Dictionary<string,string>
{
{"id","72832"},
{"name","John"}
};
var jsonData = JsonConvert.SerializeObject(data);
var contentData = new StringContent(jsonData, Encoding.UTF8, "application/json");
var response = await client.PostAsync(api, contentData);
if (response.IsSuccessStatusCode)
{
var stringData = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<object>(stringData);
}
}
Update
If the request comes back with Json data in the form `
{ "return":"8.00", "name":"John" }
you have to create result model
public class ResultModel
{
public string Name {get; set;}
public double Return {get; set;}
}
and code will be
if (response.IsSuccessStatusCode)
{
var stringData = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<ResultModel>(stringData);
var value=result.Return;
var name=Result.Name;
}
I would start off by using RestSharp.
dotnet add package RestSharp
Then you can send requests like this:
public async Task<IRestResult> PostAsync(string url, object body)
{
var client = new RestClient(url);
client.Timeout = -1;
var request = new RestRequest(Method.Post);
request.AddJsonBody(body);
var response = await client.ExecuteAsync(request);
return response;
}
Just pass in your dictionary as the body object - I would recommend creating a DTOS class to send through though.
Then you can get certain aspects of the RestResponse object that is returned like:
var returnContent = response.Content;
var statusCode = response.StatusCode;

HttpClient sending parameter null

I'm trying to send data to an api with HttpClient but parameter I'm sending keeps received as 0.
What am I doing wrong here? It's my first usage of HttpClient so it's quite possible I mixed things or made some rookie mistake.
Path is correct, I can get results from Postman.
Code I'm using is this;
static async Task GetActivityList()
{
string uri = "/api/ExtraNet/GetActivityList";
HttpClient client = new HttpClient();
int SalesPersonId = 553;
string token = my token value is here;
client.BaseAddress = new Uri("http://localhost:16513/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var postData = "{\"SalesPersonId=\":\""+SalesPersonId+"\"}";
var stringContent = new StringContent( "{\"SalesPersonId=\":\"" + SalesPersonId + "\"}", Encoding.UTF8, "application/json") ;
var content = new StringContent(postData, Encoding.UTF8, "application/json");
var response = await client.PostAsync("http://localhost:16513/api/ExtraNet/GetActivityList", stringContent);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
I managed to send the parameter this way
string uri = "/api/ExtraNet/GetActivityList";
HttpClient client = new HttpClient();
int SalesPersonId = 553;
string token = "";
client.BaseAddress = new Uri("http://localhost:16513/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var stringContent = new FormUrlEncodedContent(new[] {
new KeyValuePair<string,string>("SalesPersonId","553")
});
var response = await client.PostAsync(uri, stringContent);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
Sending the parameters as FormUrlEncodedContent did the trick.

Paypal Rest Api With RestSharp not working in xamarin android

I have got error with RestSharp component when i am call Paypal Rest API.
I have the following code using Xamarin for Android.
public async Task<PayPalGetTokenResponse> GetAccessToken()
{
var restRequest = new RestRequest("/oauth2/token", Method.POST);
// Add headers
restRequest.AddHeader("Accept", "application/json");
restRequest.AddHeader("Accept-Language", "en_US");
// Make Authorization header
restClient.Authenticator = new HttpBasicAuthenticator(Config.ApiClientId, Config.ApiSecret);
// add data to send
restRequest.AddParameter("grant_type", "client_credentials");
var response = restClient.Execute<PayPalGetTokenResponse>(restRequest);
response.Data.DisplayError = CheckResponseStatus(response, HttpStatusCode.OK);
return response.Data;
}
But got error :"Error: SecureChannelFailure (The authentication or decryption has failed.)"
I have Also use ModernHttpClient but got same error
public async Task<PayPalGetTokenResponse> GetAccessToken()
{
string clientId = Config.ApiClientId;
string secret = Config.ApiSecret;
string oAuthCredentials = Convert.ToBase64String(Encoding.Default.GetBytes(clientId + ":" + secret));
string uriString = Config.ApiUrl+"/oauth2/token";
PayPalGetTokenResponse result;
HttpClient client = new HttpClient(new NativeMessageHandler());
var h_request = new HttpRequestMessage(HttpMethod.Post, uriString);
h_request.Headers.Authorization = new AuthenticationHeaderValue("Basic", oAuthCredentials);
h_request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
h_request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue("en_US"));
h_request.Content = new StringContent("grant_type=client_credentials", UTF8Encoding.UTF8);
try
{
HttpResponseMessage response = await client.SendAsync(h_request);
//if call failed ErrorResponse created...simple class with response properties
if (!response.IsSuccessStatusCode)
{
var error = await response.Content.ReadAsStringAsync();
var errResp = JsonConvert.DeserializeObject<string>(error);
//throw new PayPalException { error_name = errResp.name, details = errResp.details, message = errResp.message };
}
var success = await response.Content.ReadAsStringAsync();
result = JsonConvert.DeserializeObject<PayPalGetTokenResponse>(success);
}
catch (Exception)
{
throw new HttpRequestException("Request to PayPal Service failed.");
}
return result;
}
Have you tried to force to modern day SSL protocol?
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
This works for me:
if (ServicePointManager.SecurityProtocol != SecurityProtocolType.Tls12)
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var client = new RestClient(payPalURL) {
Encoding = Encoding.UTF8
};
var authRequest = new RestRequest("oauth2/token", Method.POST) {
RequestFormat = DataFormat.Json
};
client.Authenticator = new HttpBasicAuthenticator(clientId, secret);
authRequest.AddParameter("grant_type","client_credentials");
var authResponse = client.Execute(authRequest);

Using a token to search on Twitter with OAuth2

Before Twitter switched to OAuth2, I was using the following query:
string atomTweetSearchURL = string.Format("http://search.twitter.com/search.atom?q={0}", searchText);
This no longer works, so now I'm trying to switch to OAuth2. I manage to successfully retrieve a token, but once I've got this, I seem to be unable to actually perform the search. Here's the latest incarnation of what I've tried:
var searchUrl = string.Format("https://api.twitter.com/1.1/search/tweets.json?q={0}&access_token={1}&token_type={2}", srchStr, twitAuthResponse.access_token, twitAuthResponse.token_type);
WebRequest srchRequest = WebRequest.Create(searchUrl);
using (var response2 = await srchRequest.GetResponseAsync())
{
Stream stream = response2.GetResponseStream();
using (StreamReader sr = new StreamReader(stream))
{
string jsonResponse = await sr.ReadToEndAsync();
}
}
This gives me a 400 - bad request.
I've also tried building the request like this:
System.Net.Http.HttpClient srchRequest = new System.Net.Http.HttpClient();
string authHdr = string.Format(srchHeaderFormat, twitAuthResponse.token_type, twitAuthResponse.access_token);
srchRequest.DefaultRequestHeaders.Add("Authorization", authHdr);
There's a massive quantity of articles out there detailing how to do this, but none of them seem to work correctly with WinRT. Can anyone point me in the right direction?
EDIT
Here's my code to get the token:
var oAuthConsumerKey = key;
var oAuthConsumerSecret = secret;
var oAuthUri = new Uri("https://api.twitter.com/oauth2/token");
var authHeaderFormat = "Basic {0}";
var authHeader = string.Format(authHeaderFormat,
Convert.ToBase64String(Encoding.UTF8.GetBytes(Uri.EscapeDataString(oAuthConsumerKey)
+ ":" +
Uri.EscapeDataString((oAuthConsumerSecret)))
));
var req = new HttpClient();
req.DefaultRequestHeaders.Add("Authorization", authHeader);
HttpRequestMessage msg = new HttpRequestMessage(new HttpMethod("POST"), oAuthUri);
msg.Content = new HttpStringContent("grant_type=client_credentials");
msg.Content.Headers.ContentType = new Windows.Web.Http.Headers.HttpMediaTypeHeaderValue("application/x-www-form-urlencoded");
HttpResponseMessage response = await req.SendRequestAsync(msg);
TwitAuthenticateResponse twitAuthResponse;
using (response)
{
string objectText = await response.Content.ReadAsStringAsync();
twitAuthResponse = JSonSerialiserHelper.Deserialize<TwitAuthenticateResponse>(objectText);
}
With the 1.1 API you don't pass the access token as part of the url, you need to include it as the Authorization header as "Bearer access_token" so you were almost there!
EDIT
To do this in the Windows.Web.Http namespace the following works:
private static async Task SearchTweets(AuthenticationResponse twitAuthResponse)
{
string srchStr = "tweet";
var client = new HttpClient();
var searchUrl = string.Format("https://api.twitter.com/1.1/search/tweets.json?q={0}", srchStr);
var uri = new Uri(searchUrl);
client.DefaultRequestHeaders.Authorization = new HttpCredentialsHeaderValue("Bearer", twitAuthResponse.AccessToken);
var response2 = await client.GetAsync(uri);
string content = await response2.Content.ReadAsStringAsync();
}
Or with System.Net.Http use the following:
This code will run the search for srchStr using the access token you already acquired as you showed in the first example:
var client = new HttpClient();
var searchUrl = string.Format("https://api.twitter.com/1.1/search/tweets.json?q={0}", srchStr);
var uri = new Uri(searchUrl);
client.DefaultRequestHeaders.Add("Authorization", string.Format("Bearer {0}", twitAuthResponse.access_token));
HttpResponseMessage response = await client.GetAsync(uri);
Task<string> content = response.Content.ReadAsStringAsync();
EDIT
This is a strange one, I tested your code and you're right it does throw an exception when attempting to add the Auth header, however the code I had used for grabbing the Access Token is almost identical but uses the System.Net.Http methods rather than the Windows.Web.Http ones that you use and it works, so I'll provide my code here, maybe this is a bug in the framework, or someone else can provide some more insight! This also uses the JSON.NET library which can be found on NuGet.
private static async Task SearchTweets(AuthenticationResponse twitAuthResponse)
{
string srchStr = "tweet";
var client = new HttpClient();
var searchUrl = string.Format("https://api.twitter.com/1.1/search/tweets.json?q={0}", srchStr);
var uri = new Uri(searchUrl);
client.DefaultRequestHeaders.Add("Authorization", string.Format("Bearer {0}", twitAuthResponse.AccessToken));
HttpResponseMessage response2 = await client.GetAsync(uri);
string content = await response2.Content.ReadAsStringAsync();
}
private async void GetAuthenticationToken()
{
var client = new HttpClient();
var uri = new Uri("https://api.twitter.com/oauth2/token");
var encodedConsumerKey = WebUtility.UrlEncode(TwitterConsumerKey);
var encodedConsumerSecret = WebUtility.UrlEncode(TwitterConsumerSecret);
var combinedKeys = String.Format("{0}:{1}", encodedConsumerKey, encodedConsumerSecret);
var utfBytes = System.Text.Encoding.UTF8.GetBytes(combinedKeys);
var encodedString = Convert.ToBase64String(utfBytes);
client.DefaultRequestHeaders.Add("Authorization", string.Format("Basic {0}", encodedString));
var data = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", "client_credentials")
};
var postData = new FormUrlEncodedContent(data);
var response = await client.PostAsync(uri, postData);
AuthenticationResponse authenticationResponse;
using (response)
{
if (response.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception("Did not work!");
var content = await response.Content.ReadAsStringAsync();
authenticationResponse = JsonConvert.DeserializeObject<AuthenticationResponse>(content);
if (authenticationResponse.TokenType != "bearer")
throw new Exception("wrong result type");
}
await SearchTweets(authenticationResponse);
}
}
class AuthenticationResponse
{
[JsonProperty("token_type")]
public string TokenType { get; set; }
[JsonProperty("access_token")]
public string AccessToken { get; set; }
}

Categories

Resources