Getting null response - azure API calling c# - c#

Here I try to hit the API which is hosted in azure. It have to give a response as a result value - "Registered Successfully".
But the response that I got when debugging the program is "null". And also I used to call this API in a try catch block. It doesn't enter into catch block but shows a null response.
But it return valid response when I run it in POSTMAN application.
Please anyone let me know what is the problem in my code.
postman screenshot This is the postman screenshot
Here is my code
HttpClient client = new client();
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", ApiKey);
client.DefaultRequestHeaders.Add("Accept", "application/json");
string strAttn = DateTime.Now.TimeOfDay.ToString();
strAttn += "~" + personName;
strAttn += "~" + val;
string Uri = "https://orgdev.azure-api.net/APIDev/Attendance?guid=" + personID + "&timeofattendance=" + strAttn + "";
try
{
var lntResponse = await client.GetAsync(Uri);
}
catch (Exception ex)
{
string exc = ex.Message.ToString();
}

Related

How to connect WPF(C#) app to a Node.js API route?

So I have a WPF application that I want to connect to a RESTful API made with Node.js express server, I have the API on my local pc and the WPF app as well and I want to connect the WPF app to a route in the API called "meals", is there a way to do that?
Yes there is a way to do that
the below code sends a post and a get requests to the API just change the port to whatever port you're running your API on
private static readonly HttpClient client = new HttpClient();
public async void SendPostRequestToAPI(){
// POST REQUEST
try
{
var values = new Dictionary<string, string>
{
{ "thing1", "hello" },
{ "thing2", "world" }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("http://localhost:port", content);
var responseString = await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
Console.WriteLine("Error..... " + ex.StackTrace);
}
// GET REQUEST
try
{
var responseString = await client.GetStringAsync("http://localhost:port");
}
catch (Exception ex)
{
Console.WriteLine("Error..... " + ex.StackTrace);
}
}
don't forget to use the following directive
using System.Net.Http;

Getting "Response status code does not indicate success: 500 (Internal Server Error)" Error

At my job, we have a service that processes JSON files.
Usually, it will split a larger file into smaller files so it can multithread and process more splits faster.
Occassionally, we'll see an API Communication Failure message, and when looking into the logs, I'll see this: "Response status code does not indicate success: 500 (Internal Server Error)"
It doesn't happen all of the time, but a few times an hour. We have very high traffic, so its not even a large percentage of the files that are failing. Could someone please shed some light on what could possibly be wrong?
Here is the code where it is happening:
public class CommunicationAPI
{
static int iAPIConnectionTimeOut = int.Parse(ConfigurationManager.AppSettings["APIConnectionTimeOut"]); //15 minutes, so a timeout isn't the issue.
public static async Task<string> PostInboundActivityAsync(string sUrl, string sContent, long lSysServiceThread)
{
string sResponse = string.Empty;
try
{
using (HttpClient client = new HttpClient())
{
client.Timeout = TimeSpan.FromSeconds(iAPIConnectionTimeOut);
StringContent strContent = new StringContent("'" + sContent + "'", Encoding.UTF8, "application/json");
var response = client.PostAsync(sUrl, strContent);
var apiResponse = await response;
if (apiResponse != null && HttpStatusCode.PreconditionFailed == apiResponse.StatusCode)
{
return sResponse = apiResponse.Content.ReadAsStringAsync().Result;
}
else
{
apiResponse.EnsureSuccessStatusCode();
}
sResponse = apiResponse.Content.ReadAsStringAsync().Result;
// check if we received response 'OK' 200 status
if (string.IsNullOrWhiteSpace(sResponse))
{
sResponse = apiResponse.ReasonPhrase;
}
}
}
catch (Exception ex)
{
LogManager.WriteToThreadLog("Exception in API Call :" + ex.Message, lSysServiceThread);
sResponse = "EXCEPTION";
}
return sResponse;
}
}
Thank you!

Xamarin Android client post JSON to Node JS web service

I am having trouble with sending JSON data from my Android application written in C# using Xamarin Android (MvvmCross).
The function in Android application could run with no exception; however, my web service (written in Node JS using Express) seems not detecting the post request on its endpoint. Note that the other endpoints which use get (to send the data from web service to Android app) are working perfectly.
Below is my function to post my data to my web service
public async Task<int> insertSales(IEnumerable<Models.SalesTable> newsales)
{
/*ServerDatabaseApi.insertSalesEndpoint = "http://" + ipAddress + ":" + port +
"/insertsales";*/
WebRequest request = WebRequest.CreateHttp(ServerDatabaseApi.insertSalesEndpoint);
request.Method = "POST";
request.ContentType = "application/json";
try
{
using (var streamwriter = new StreamWriter(await request.GetRequestStreamAsync()))
{
string json = JsonConvert.SerializeObject(newsales, Formatting.Indented);
streamwriter.Write(json);
streamwriter.Flush();
}
return 1;
}
catch (WebException we)
{
return 0;
}
}
When running the function above, it is always succeed (return 1; always executes). I have also tried checking the JSON serialization and it is working perfectly fine.
Below also attached the endpoint code used to serve the data.
/*endpoint for inserting a new sales to sales table*/
app.post('/insertsales', function(appReq, appRes){
console.log("Insert sales; count : "+ appReq.body.length);
sql.connect(conn).then(function(){
console.log("Insert sales; count : "+ appReq.body.length);
for (var i = 0 ; i < appReq.body.length ; i++) {
new sql.Request()
.query("insert into SalesTable " +
"values ('"+appReq.body[i].DocumentNo+"','"+appReq.body[i].DateCreated+"','"+appReq.body[i].Location+"',"+
appReq.body[i].TotalDiscountAmount+","+appReq.body[i].Total+",'"+appReq.body[i].SalesmanId+"','"+
appReq.body[i].CustomerId+"',"+appReq.body[i].Latitude+","+appReq.body[i].Longitude+")")
.catch(function(err){
console.log(err);
});
}
}).catch(function(err){
console.log(err);
});
});
I tried to trace whether it reached the endpoint or not using console.log. However, it never executes.
Could you help me to spot where I went wrong? Thanks in advance.
There's nothing in your .NET code that actually sends the WebRequest. You create the request, write some JSON to it's stream, and flush it. Here's a simple way to make the network call (untested):
public async Task<int> InsertSales(IEnumerable<Models.SalesTable> newSales)
{
var ipAddress = "";// your IP address here
var port = ""; // your port here
var endpoint = $"http://{ipAddress}:{port}/insertsalesline";
var requestString = JsonConvert.SerializeObject(newSales);
var content = new StringContent(requestString, Encoding.UTF8, "application/json");
using (var client = new HttpClient())
{
var reponse = await client.PostAsync(endpoint, content);
if (reponse.IsSuccessStatusCode)
return 1;
else
return 0;
}
}

C# HttpClient; How to make safe async calls?

I have a site that exercises a third party API. This API will tell me the values of accounts for a user. The API has become unresponsive, and this has highlighted a flaw in my code. I am getting the exception "Thread was being aborted." in the try-catch trap around the call, and in EventViewer I can see the HttpException RequestTimedOut.
I am trying to use HttpClient, in a synchronous manner. This works fine when the API is responsive, but it is coming apart now that the API is very slow to respond.
I have an overview page that tries to gather all the account values for all users.
There are 3 types of users (CLIENT, LIAISON, MEMBER). The page makes three asynchronous Javascript calls for each type of account. The fact that there are three calls made is (most probably) a red-herring, but I am declaring it to be safe.
The server takes each call, gets the users for each call. So, for the CLIENT call, the system pulls up the all the CLIENT users, and serially steps through them. It makes an HTTP request per CLIENT user to get the account value.
Each call has a new HttpClient object created for it, wrapped in a using statement.
I strongly suspect that IIS is spotting the idle thread and shutting it down, which is fair enough.
How can I make the API call so that I return the thread to the pool until I get a response?
private static string getTotalAssets(string blockChainAddress, string identity)
{
var prefix = "getTotalAssets() - ";
string msg = "";
using (var handler = new HttpClientHandler { UseCookies = false, PreAuthenticate = true })
using (var client = new HttpClient(handler))
{
// Timeout
TimeSpan tsTimeout = new TimeSpan(0, 0, 0, _timeout);
client.Timeout = tsTimeout;
var message = new HttpRequestMessage(HttpMethod.Post, _urlSettleAPIGetTotalAssets);
// Accept Json
message.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(Constants.MIME_JSON));
// Form the content to send
string content = getTotalAssetsContent(blockChainAddress);
// Add to the message
message.Content = new StringContent(content);
// Make API Call
string sCallRef = "GET TOTAL ASSETS FOR [" + identity + "]";
Tuple<HttpResponseMessage, string> result = MakeAPICall(client, message, content, sCallRef);
if (result.Item1 == null)
return result.Item2; // Error during call
// Call returned
HttpResponseMessage response = result.Item1;
string responseString = result.Item2;
if (!response.IsSuccessStatusCode)
{
msg = "Response Status Code: " + response.StatusCode.ToString();
logger.Debug(prefix + msg);
return "Error [" + result.Item2 + "]; " + msg;
}
// Else, call returned 200-OK
logger.Debug(prefix + "Response:\r\n" + responseString + "\r\n");
return processGetTotalAssetsResponseString(responseString);
} // end of using...
}
public static Tuple<HttpResponseMessage, string> MakeAPICall(HttpClient client, HttpRequestMessage message, string content, string callRef)
{
var prefix = "MakeAPICall() - ";
string msg = "";
HttpResponseMessage responseMessage;
string responseString = "";
try
{
responseMessage = client.SendAsync(message).GetAwaiter().GetResult();
responseString = responseMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult();
return new Tuple<HttpResponseMessage, string>(responseMessage, responseString);
}
catch (Exception ex)
{
msg = "Exception during call; \r\nBaseMessage:[" + ex.GetBaseException().Message + "]; \r\nMessage:[" + ex.Message + "]";
logger.Warn(prefix + msg);
return new Tuple<HttpResponseMessage, string>(null, msg);
}
} // end of MakeAPICall()

Jenkins returns (403) Forbidden when posting delete request to API

I am trying to delete a Jenkins job using a C# script.
When I run the code, it actually works. The job is deleted. However, Jenkins still returns a 403 error. Am I doing something wrong?
This is my code:
String credentials = ConfigurationManager.AppSettings["jenkinsUser"] + ":" + ConfigurationManager.AppSettings["jenkinsKey"];
String authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials));
try
{
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.Authorization] = "Basic " + authorization;
string HtmlResult = wc.UploadString(ConfigurationManager.AppSettings["jenkinsDeleteJobUrl"], "POST", "");
Console.WriteLine("Success");
}
}
catch(WebException e)
{
Console.WriteLine("Something went wrong");
throw e;
}
the url I use is [My Jenkins url]/job/{0}/doDelete
I also tried using HttpWebRequest with the same result. Hope someone knows the answer.
[Edit] note that when I use Postman to do the same request, it goes through all right, redirecting to the Jenkins main page with a return code 200.
This is the Postman call:
POST /job/[jobname]/doDelete HTTP/1.1
Host: [my jenkins url]
Authorization: Basic [my auth hash]
Cache-Control: no-cache
I think the problem is that, when you delete a Jenkins job using the doDelete url, you get redirected to your Jenkins homepage. Since you do this programatically, Jenkins does not recognize a user session (even though your original request contained an Authorization header), resulting in a forbidden code.
As a work-around, I did the following:
try {
string credentials = ConfigurationManager.AppSettings["jenkinsUser"] + ":" + ConfigurationManager.AppSettings["jenkinsKey"];
string authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials));
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.Authorization] = "Basic " + authorization;
string HtmlResult = wc.UploadString(String.Format(ConfigurationManager.AppSettings["jenkinsDeleteJobUrl"], jobName), "POST", "");
}
}
catch (WebException e)
{
// ignore the 403 error for now
HttpWebResponse errorResponse = e.Response as HttpWebResponse;
if(errorResponse.StatusCode != HttpStatusCode.Forbidden)
{
throw e;
}
}
// if the job no longer exists, it is proof that the request went through
if(!JenkinsHelper.GetJenkinsJobs().Contains(jobName))
{
Console.WriteLine("Job successfully deleted.");
return true;
}
else
{
Console.WriteLine("Could not delete job.");
return false;
}
with this helper function, in which JenkinsJobListUrl = [MyJenkinsUrl]/api/xml?xpath=hudson/job/name&wrapper=jobs
public static List<string> GetJenkinsJobs()
{
try
{
string credentials = ConfigurationManager.AppSettings["jenkinsUser"] + ":" + ConfigurationManager.AppSettings["jenkinsKey"];
string authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials));
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.Authorization] = "Basic " + authorization;
string HtmlResult = wc.DownloadString(String.Format(ConfigurationManager.AppSettings["jenkinsJobListUrl"]));
XDocument doc = XDocument.Parse(HtmlResult);
return doc.Root.Elements("name").Select(element => element.Value).ToList();
}
}
catch (WebException e)
{
Console.WriteLine("Could not retreive Jenkins job list");
throw e;
}
}
I know it isn't pretty, but for lack of a better solution this gets the job done.
Hope this helps people who have been struggling with this too. If you find a better solution, please let me know.

Categories

Resources