I am working on Azure Function (Http Trigger), and came across with this task.
I am trying to display the output of method (ListVendors.Run(logger)) into inside variable (responseMessage) so that the values would be carried into Http post.
public static class Function1
{
[FunctionName("HttpTrigger_1111_1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
///Calling from other method starts:
ILogger logger = Bootstrap.Logger("Program");
ListVendors.Run(logger);
///Calling from other method ends:
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
string responseMessage = string.IsNullOrEmpty(name)
? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
: $"Hello, {name}. This HTTP triggered function executed successfully.";
return new OkObjectResult(responseMessage);
}
}
Basically, I am trying to insert the output of:
ListVendors.Run(logger);
Inside "responseMessage".
return new OkObjectResult(responseMessage);
How do I modify the code to do that?
Bottom is code for ListVendors:
public static class ListVendors
{
public static void Run(ILogger logger)
{
OnlineClient client = Bootstrap.Client(logger);
ReadByQuery query = new ReadByQuery()
{
ObjectName = "VENDOR",
PageSize = 2, // Keep the count to just 2 for the example
Fields =
{
"RECORDNO",
"VENDORID",
}
};
logger.LogInformation("Executing query to Intacct API");
Task<OnlineResponse> task = client.Execute(query);
task.Wait();
OnlineResponse response = task.Result;
Result result = response.Results[0];
try
{
dynamic json = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(result.Data));
string jsonString = json.ToString();
logger.LogDebug(
"Query successful - page 1 [ Total count={0}, Data={1} ]",
result.TotalCount,
jsonString
);
Console.WriteLine("Page 1 success! Number of vendor objects found: " + result.TotalCount + ". Number remaining: " + result.NumRemaining);
} catch (NullReferenceException e)
{
logger.LogDebug("No response in Data. {0}", e);
}
LogManager.Flush();
int i = 1;
while (result.NumRemaining > 0 && i <= 3 && !string.IsNullOrEmpty(result.ResultId))
{
i++;
ReadMore more = new ReadMore()
{
ResultId = result.ResultId
};
Task<OnlineResponse> taskMore = client.Execute(more);
taskMore.Wait();
OnlineResponse responseMore = taskMore.Result;
Result resultMore = responseMore.Results[0];
try
{
dynamic resultMoreJson =
JsonConvert.DeserializeObject(JsonConvert.SerializeObject(resultMore.Data));
string resultMoreJsonString = resultMoreJson.ToString();
logger.LogDebug(
"Read More successful - page " + i + " [ Total remaining={0}, Data={1} ]",
resultMore.NumRemaining,
resultMoreJsonString
);
Console.WriteLine("Page " + i + " success! Records remaining: " + resultMore.NumRemaining);
}
catch (NullReferenceException e)
{
logger.LogDebug("No response in Data. {0}", e);
}
finally
{
LogManager.Flush();
}
}
Console.WriteLine("Successfully read " + i + " pages");
}
}
}
Related
I'm new to working with async and I'm trying to build a Cefsharp application that collects data from an external API, stores it in local variables and then exports these through JavaScript to HTML. It's not a beautiful implementation and I'm sure my code is pretty awful but here goes:
My application performs a tick every 5 seconds, where it executes a HTTP Post request and stores the result in a QuickType (app.quicktype.io) list. This is the tick:
private async void timer1_Tick(object sender, EventArgs e)
{
await chromeBrowser.WaitForInitialLoadAsync();
if (httpPost.ConnectionSuccesful())
{
var devtoolsContext = await chromeBrowser.CreateDevToolsContextAsync();
var postResult = await httpPost.SendPost("robot_info");
try {
var result = Welcome.FromJson(postResult);
foreach (var robot in result.Result.Robots.Select((value, i) => (value, i)))
{
Console.WriteLine(robot.value.Id);
if (robot.value.ChargingStateCode == 9 || robot.value.ChargingStateCode == 12)
await devtoolsContext.EvaluateFunctionAsync("function setBatteryCharge() { var batteryLevel = jQuery('#robot" + robot.i + "Charge'); batteryLevel.css('width', "+ robot.value.StateOfCharge + " + '%'); batteryLevel.text('Charging'); batteryLevel.addClass('high'); batteryLevel.removeClass('medium'); batteryLevel.removeClass('low'); }");
else if (robot.value.StateOfCharge > 75)
await devtoolsContext.EvaluateFunctionAsync("function setBatteryHigh() { var batteryLevel = jQuery('#robot" + robot.i + "Charge'); batteryLevel.css('width', " + robot.value.StateOfCharge + " + '%'); batteryLevel.text(" + robot.value.StateOfCharge + " + '%'); batteryLevel.addClass('high'); batteryLevel.removeClass('medium'); batteryLevel.removeClass('low'); }");
else if (robot.value.StateOfCharge >= 50)
await devtoolsContext.EvaluateFunctionAsync("function setBatteryMedium() { var batteryLevel = jQuery('#robot" + robot.i + "Charge'); batteryLevel.css('width', " + robot.value.StateOfCharge + " + '%'); batteryLevel.text(" + robot.value.StateOfCharge + " + '%'); batteryLevel.addClass('medium'); batteryLevel.removeClass('high'); batteryLevel.removeClass('low'); }");
else
await devtoolsContext.EvaluateFunctionAsync("function setBatteryLow() { var batteryLevel = jQuery('#robot" + robot.i + "Charge'); batteryLevel.css('width', " + robot.value.StateOfCharge + " + '%'); batteryLevel.text(" + robot.value.StateOfCharge + " + '%'); batteryLevel.addClass('low'); batteryLevel.removeClass('high'); batteryLevel.removeClass('medium'); }");
}
}
catch (ArgumentNullException Nex) {
Console.Write("[Error] - " + Nex.Message);
}
catch (Exception ex)
{
Console.WriteLine("[Error] - " + ex.Message);
}
}
else
Console.WriteLine("[Error] - Check connection or access to API server.");
}
I'm currently trying to update the battery level and it successfully does this for the first tick (the JavaScript works as intended and both the css, classes and text is changed). Then it stops working. I've checked that the correct results are coming in from the HTTP Post and that the data is stored properly in the local variables. The problem seems to occur in the foreach. I've tried to read up about async a bit but I can't seem to find the culprit. After the first execution of the code, something seems to be blocking the iteration of the for each. I'm using Cefsharp.Winforms and Cefsharp.Puppeteer.
Any idea on why this is happening? Also thankful for any pointers or tips on how to improve the code.
EDIT: This is the Console Output
[Query] Sending post request to xxx with method 'robot_info'
[Success] - API Post Request was succesful.
PR1#11
PR1#15
[Query] Sending post request to xxx with method 'robot_info'
[Success] - API Post Request was succesful.
PR1#11
[Query] Sending post request to xxx with method 'robot_info'
[Success] - API Post Request was succesful.
PR1#11
The first iteration goes through fine.
EDIT2: This is the timer
public void InitTimer()
{
timer1 = new Timer();
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = 5000;
timer1.Start();
}
EDIT3: Method SendPost
public async Task<string> SendPost(string method)
{
HttpClient httpClient = new HttpClient();
string data = new JavaScriptSerializer().Serialize(new
{
jsonrpc = "2.0",
method = method,
id = Guid.NewGuid().ToString()
});
StringContent content = new StringContent(data, System.Text.Encoding.UTF8, "application/json");
try
{
Console.WriteLine("[Query] Sending post request to " + url.ToString() + " with method '" + method + "'");
HttpResponseMessage response = await httpClient.PostAsync(url, content).ConfigureAwait(false);
string result = await response.Content.ReadAsStringAsync();
if (IsValidJson(result))
{
Console.WriteLine("[Success] - API Post Request was succesful.");
return result;
}
else
return null;
} catch (HttpRequestException hre)
{
Console.WriteLine("[Error]: " + hre);
return null;
}
}
EDIT4: Structure of Welcome
public partial class Welcome
{
[JsonProperty("jsonrpc")]
public string Jsonrpc { get; set; }
[JsonProperty("result")]
public Result Result { get; set; }
[JsonProperty("id")]
public string Id { get; set; }
}
public partial class Result
{
[JsonProperty("timestamp")]
public long Timestamp { get; set; }
[JsonProperty("robots")]
public List<Robot> Robots { get; set; }
}
Robots is a list with a bunch of longs and ints.
I have an asp.net web API. I have a filter attribute and OnAuthorization I am returning HttpResponseMessage as follows.
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
//Check Request Start-End Period
if (!CheckRequestTime())
{
var response = new HttpResponseMessage
{
StatusCode = (HttpStatusCode) 429,
ReasonPhrase = "Invalid Request Time",
Content = new StringContent("Requests are permitted between " +
WebConfigurationManager.AppSettings["TimeStart"].ToString() +
" AM and " + WebConfigurationManager.AppSettings["TimeEnd"].ToString() +
" PM.")
};
actionContext.Response = response;
}
}
A Client wants me to return ResponseMessageResult which means adding Message property to the response as follows:
{
"Message": "Requests are permitted between 11:00 AM and 22:30 PM."
}
UPDATE
This solved my problem.
Content = new StringContent("{\"Message\":\"Requests are permitted between " +
WebConfigurationManager.AppSettings["TimeStart"].ToString() +
" AM and " + WebConfigurationManager.AppSettings["TimeEnd"].ToString() +
" PM.\"}", System.Text.Encoding.UTF8, "application/json"),
I'm trying to change my Restsharp Client to work async instead of sync.
Each of my API-Calls referes to the GetAsync<T> method. When I try now to change the Client to call ExecuteAsync<T> instead of Execute i got this error:
Delegate 'Action, RestRequestAsyncHandle>' does not take 1 Arguments
I'm using RestSharp Version 106.6.10 currently.
Here is my GetAsyncMethod:
public async Task<T> GetAsync<T>(string url, Dictionary<string, object> keyValuePairs = null)
{
try
{
// Check token is expired
DateTime expires = DateTime.Parse(Account.Properties[".expires"]);
if (expires < DateTime.Now)
{
// Get new Token
await GetRefreshTokenAsync();
}
// Get AccessToken
string token = Account.Properties["access_token"];
if (string.IsNullOrEmpty(token))
throw new NullReferenceException("AccessToken is null or empty!");
// Create client
var client = new RestClient()
{
Timeout = 3000000
};
//Create Request
var request = new RestRequest(url, Method.GET);
request.RequestFormat = DataFormat.Json;
request.AddHeader("Authorization", "Bearer " + token);
// Add Parameter when necessary
if (keyValuePairs != null)
{
foreach (var pair in keyValuePairs)
{
request.AddParameter(pair.Key, pair.Value);
}
}
// Call
var result = default(T);
var asyncHandle = client.ExecuteAsync<T>(request, restResponse =>
{
// check respone
if (restResponse.ResponseStatus == ResponseStatus.Completed)
{
result = restResponse.Data;
}
//else
// throw new Exception("Call stopped with Status: " + response.StatusCode +
// " Description: " + response.StatusDescription);
});
return result;
}
catch (Exception ex)
{
Crashes.TrackError(ex);
return default(T);
}
}
Here one of the calling Methods:
public async Task<List<UcAudit>> GetAuditByHierarchyID(int hierarchyID)
{
string url = AuthSettings.ApiUrl + "/ApiMethod/" + hierarchyID;
List<UcAudit> auditList = await GetAsync<List<UcAudit>>(url);
return auditList;
}
When I Change the T in ExecuteAsync<T> in one of my classes the error is gone. How can I change the method to work async with <T>???
With the info from Lasse Vågsæther Karlsen I found the solution.
This is the start:
var asyncHandle = client.ExecuteAsync<T>(request, restResponse =>
{
// check respone
if (restResponse.ResponseStatus == ResponseStatus.Completed)
{
result = restResponse.Data;
}
//else
// throw new Exception("Call stopped with Status: " + response.StatusCode +
// " Description: " + response.StatusDescription);
});
Worked for me :
client.ExecuteAsync<T>(request, (response, asyncHandle )=>
{
//check respone
if (response.StatusCode == HttpStatusCode.OK)
{
result = response.Data;
}
else
throw new Exception("Call stopped with Status: " + response.StatusCode +
" Description: " + response.StatusDescription);
});
Thank you!
I am developing an app using instagram api to bring feed to my website. I have following code but when i try to access the access_token using the code provided by Instagram it's giving me `400 Bad request error. I would be much obliged if someone could help me to overcome this problem. Many Thanks
string code="";
public ActionResult Index()
{
if (!String.IsNullOrEmpty(Request["code"]))
{
code = Request["code"].ToString();
GetDataInstagramToken();
}
return View();
}
public ActionResult Instagram()
{
var client_id = ConfigurationManager.AppSettings["instagram.clientid"].ToString();
var redirect_uri = ConfigurationManager.AppSettings["instagram.redirecturi"].ToString();
string url = "https://api.instagram.com/oauth/authorize/?client_id=" + client_id + "&redirect_uri=" + redirect_uri + "&response_type=code";
Response.Redirect(url);
return View();
}
public void GetDataInstagramToken()
{
var json = "";
var page = HttpContext.CurrentHandler as Page;
try
{
NameValueCollection parameters = new NameValueCollection();
parameters.Add("client_id", ConfigurationManager.AppSettings["instagram.clientid"].ToString());
parameters.Add("client_secret", ConfigurationManager.AppSettings["instagram.clientsecret"].ToString());
parameters.Add("grant_type", "authorization_code");
parameters.Add("redirect_uri", ConfigurationManager.AppSettings["instagram.redirecturi"].ToString());
parameters.Add("code", code);
WebClient client = new WebClient();
var result = client.UploadValues("https://api.instagram.com/oauth/access_token", "post", parameters);
var response = System.Text.Encoding.Default.GetString(result);
// deserializing nested JSON string to object
var jsResult = (JObject)JsonConvert.DeserializeObject(response);
string accessToken = (string)jsResult["access_token"];
int id = (int)jsResult["user"]["id"];
//This code register id and access token to get on client side
page.ClientScript.RegisterStartupScript(this.GetType(), "GetToken", "<script> var instagramaccessid=\"" + #"" + id + "" + "\"; var instagramaccesstoken=\"" + #"" + accessToken + "" + "\";</script>");
}
catch (Exception ex)
{
throw;
}
}
I am getting exception at
var result = client.UploadValues("https://api.instagram.com/oauth/access_token", "post", parameters);
In this line
client.UploadValues("https://api.instagram.com/oauth/access_token", "post", parameters);
You don't send any value to Instagram. If you check your parameter you can see your key but you cant see any value.
Try this:
public async void GetTokenFromCode()
{
var values = new Dictionary<string, string> {
{ "client_id","Your ChatId" },
{ "client_secret", "Your Client Secret" },
{ "grant_type", "authorization_code" },
{ "redirect_uri", "Your Redirect url"},
{ "code", "code" } };
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("https://api.instagram.com/oauth/access_token", content);
var responseString = await response.Content.ReadAsStringAsync();
}
I'm working on a Xamarin.Forms application in which I'm downloading some data from the server and showing them on the screen. This data is downloaded every 5-10 seconds in order to keep the application updated. My code for the data download looks like this:
public async Task<List<string>> RefreshProgressPageAsync()
{
var uri = new Uri(string.Format("http://someurladdress1"));
List<string> returnValue = new List<string>();
try
{
var response = await client.GetAsync(uri);
string allResult = string.Empty;
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
string[] valuePartsArray = result.Split(',');
string id = valuePartsArray[0].Substring(valuePartsArray[0].IndexOf(':') + 1);
string name = valuePartsArray[1].Substring(valuePartsArray[1].IndexOf(':') + 1);
string value = valuePartsArray[2].Substring(valuePartsArray[2].IndexOf(':') + 1);
returnValue.Add(string.Format("{0}|{1}|{2}", id, name, value));
}
uri = new Uri(string.Format("http://someurladdress2"));
response = await client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
string[] valuePartsArray = result.Split(',');
string id = valuePartsArray[0].Substring(valuePartsArray[0].IndexOf(':') + 1);
string name = valuePartsArray[1].Substring(valuePartsArray[1].IndexOf(':') + 1);
string value = valuePartsArray[2].Substring(valuePartsArray[2].IndexOf(':') + 1);
returnValue.Add(string.Format("{0}|{1}|{2}", id, name, value));
}
return returnValue;
}
catch (Exception ex)
{
Debug.WriteLine(#" ERROR {0}", ex.Message);
return new List<string>();
}
}
Client is the HttpClient. There are two calls for the client because I want to download two different set of data in one RefreshProgressPageAsync call.
Now my problem with this is when second await client.GetAsync(uri) happens, I get a null point exception somewhere in the GetAsynch call, which is not caught by the try-catch block. I do have a workaround by not parsing the string and instead send it as is, but my question is what could cause this NullPointException?