Error reusing some async json method on windows phone - c#

EDIT 1: I added below the code who calls and uses the second method, and the error and data I recive
First of all sorry if my English isn't good enough, and sorry if there is another thread with the solution. I haven't found it.
Ok, I'm making a windows phone 8 app that uses a lot of info from a web service. The app makes different Json Post and uses the info. I maked a method for Posting that WORKS:
public static async void checkdeviceid()
{
//Where we are posting to:
Uri theUri = new Uri("urlofexample");
//Create an Http client
HttpClient aClient = new HttpClient();
//Class that will be serialized into Json
objetoslistas.checkdeviceidinput paquete = new objetoslistas.checkdeviceidinput();
//Set some values
paquete.Text = "deviceID";
paquete.Text2 = App.device_id;
//serialize data
var serializado = JsonConvert.SerializeObject(paquete);
//Post the data
HttpResponseMessage aResponse = await aClient.PostAsync(theUri, new StringContent(JsonConvert.SerializeObject(paquete), Encoding.UTF8, "application/json"));
if (aResponse.IsSuccessStatusCode)
{
string res = await aResponse.Content.ReadAsStringAsync();
var respuestaperfil = JsonConvert.DeserializeObject<objetoslistas.checkdeviceidoutput>(res.ToString());
//Do something with the data
}
else
{
// show the response status code
String failureMsg = "HTTP Status: " + aResponse.StatusCode.ToString() + " - Reason: " + aResponse.ReasonPhrase;
}
}
This code its actually working, but the fact it's that my app will have maybe 30 or 40 diferent POST, so I tried to make a reusable method like this:
public static async Task<string> jsonPOST(Uri theUri, object paquete)
{
//Create an Http client and set the headers we want
HttpClient aClient = new HttpClient();
//serialize data
var serializado = JsonConvert.SerializeObject(paquete);
//Post the data
HttpResponseMessage aResponse = await aClient.PostAsync(theUri, new StringContent(JsonConvert.SerializeObject(paquete), Encoding.UTF8, "application/json"));
if (aResponse.IsSuccessStatusCode)
{
string res = await aResponse.Content.ReadAsStringAsync();
return res;
}
else
{
// show the response status code
String failureMsg = "HTTP Status: " + aResponse.StatusCode.ToString() + " - Reason: " + aResponse.ReasonPhrase;
return failureMsg;
}
}
This code gives me problems in the main, were it's called. As I can understand, the problem is that, as the method calls some await process, the rest of the code continues with the execution without expect for the await result...
The code in Main is:
objetoslistas.checkdeviceidinput paquete = new objetoslistas.checkdeviceidinput();
paquete.Text = "deviceID";
paquete.Text2 = App.device_id;
Uri url = new Uri("urlofhteservice");
Task<string> recibo = metodosJson.jsonPOST(url, paquete);
var respuestaperfil = JsonConvert.DeserializeObject<objetoslistas.checkdeviceidoutput>(recibo.ToString);
if (respuestaperfil.Text2 == null)
{
IsolatedStorageSettings.ApplicationSettings["DeviceRegistered"] = true;
}
else
{
IsolatedStorageSettings.ApplicationSettings["DeviceRegistered"] = false;
}
And I recive this error (translated from google translator, sorry)
There was an exception of type 'Newtonsoft.Json.JsonReaderException' in Newtonsoft.Json.DLL but not controlled in the user code
The data I have in "recibo" is
recibo Id = 1, Status = WaitingForActivation, Method = "{null}", Result = "{Not yet computed}" System.Threading.Tasks.Task<string>
So as I understand the await method is still waiting.
Was I clear?
Thanks

Related

PostAsync call vanishes and web page becomes available again

I have a web page that I'm trying to call a web service and I'm having it skip out of the process when called.
Here's what I'm referring to...
When I call this method after the customer enters in their check information:
public CheckInfo SubmitCheck(CheckInfo checkInfo)
{
try
{
var check = new Check();
check.account_number = checkInfo.CheckAccountNumber;
check.transit_number = checkInfo.CheckRoutingNumber;
check.amount = checkInfo.Amount.ToString();
check.check_number = checkInfo.CheckNumber;
check.bill_to_city = checkInfo.City;
check.bill_to_country = "US";
check.bill_to_postal_code = checkInfo.Zip;
check.bill_to_street = checkInfo.Street;
check.bill_to_state = checkInfo.State;
check.name_on_check = checkInfo.NameOnCheck;
check.transaction_type = "sale";
check.account_type = checkInfo.AccountType;
check.check_type = checkInfo.CheckType;
var ent = new SuburbanPortalEntities();
var gatewaySettings = (from x in ent.GatewayUsers
where x.TokenId == CurrentCustomerSession.Current.TokenId &&
x.Gateway.Name == "DirectAch2"
select x).FirstOrDefault();
var credentials = new Authentication();
credentials.password = gatewaySettings.Password;
credentials.username = gatewaySettings.UserName;
var response = Process.SubmitCheck(credentials, check).Result;
The public class that calls the private class:
public static async Task<Response> SubmitCheck(Authentication authentication, Check check)
{
return await Submit(authentication, check, PaymentTypes.Check);
}
The SubmitCheck Method:
private static async Task<Response> Submit(Authentication authentication, Object payment, PaymentTypes paymentType)
{
var resp = new Response();
try
{
var client = new HttpClient();
var bodyjson = JsonConvert.SerializeObject(authentication);
var bodycontent = new StringContent(bodyjson, Encoding.UTF8, "application/json");
var authenticationPost =
await client.PostAsync("https://someplace.com/api/v2/Identity", bodycontent);
var bodyResponseJson = await authenticationPost.Content.ReadAsStringAsync();
When I get to this line, it just returns out of the method and it doesn't continue on with anything, it's like I never executed this method.
var authenticationPost =
await client.PostAsync("https://someplace.com/api/v2/Identity", bodycontent);
No other code is executed after this line. It just stops and the web page becomes available again. I have the method wrapped in a try catch but the catch isn't.. catching anything.
I'm at a loss at this poing, any suggestions?
EDIT#1
I wrapped the line in a try catch as suggested.
try
{
authenticationPost =
await client.PostAsync("https://someplace.com/api/v2/Identity", bodycontent);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
It's stepping out of the try/catch and never executing any more code after that. No exception is caught, nothing, it just runs the line and leaves the method.
Here's your problem:
var response = Process.SubmitCheck(credentials, check).Result;
Don't block on async code, as I describe on my blog. This is a common mistake for those new to async/await. Instead of Result, use await:
public async Task<CheckInfo> SubmitCheck(CheckInfo checkInfo)
{
...
var response = await Process.SubmitCheck(credentials, check);
Note that you'd then need to await the call to SubmitCheck, and so on. It's async all the way.
Side note: I recommend using the standard pattern of *Async suffixes on your method names; it makes it clearer in the code that their return values need to be awaited:
public async Task<CheckInfo> SubmitCheckAsync(CheckInfo checkInfo)
{
...
var response = await Process.SubmitCheckAsync(credentials, check);

Need help to find where does API takes data from in ASP.NET MVC

I am a begginer and i work in a MVC project which I cant understand it well yet.
I can't understand where does the API takes data from when I try to connect in Login Screen.
It doesn't use Entity Framework and there isn't a json with the data.
When I enter Id and Pass it calls an API (GetAPIResponse) which somehow finds that is correct.
Need help to understand the code and the logic behind it.
LoginBL class contains:
public bool IsAuthenticated(LoginEntity user)
{
string url = string.Empty;
string callType = string.Empty;
string server = string.Empty;
try
{
// get URL, Call type, Server from config file
url = ConfigurationManager.AppSettings["login_url"].ToString();
callType = ConfigurationManager.AppSettings["calltype"].ToString();
server = ConfigurationManager.AppSettings["server"].ToString();
// Encrypt password
string password = Scrambler.GenerateMD5Hash(user.Password);
// Prepare content for the POST request
string content = #"calltype=" + callType + "&server=" + server + "&user=" + user.UserName + "&pass=" + password + "";
Debug.WriteLine("Callcenter login url: " + content);
HttpResponseMessage json_list = ApiCallBL.GetAPIResponse(url, content);
LoginResponseEntity obj = new LoginResponseEntity();
obj = JsonConvert.DeserializeObject<LoginResponseEntity>(json_list.Content.ReadAsStringAsync().Result);
Debug.WriteLine(callType + " Response: " + json_list.Content.ReadAsStringAsync().Result);
//if API resultCode return 0 then user details and token save in session for further use
if (obj.ResultCode == 0)
{
int restrict = obj.UserInfo.RestrictCallType.HasValue ?
obj.UserInfo.RestrictCallType.Value : 0;
HttpContext.Current.Session["user_id"] = obj.UserInfo.usr_id;
HttpContext.Current.Session["user_name"] = obj.UserInfo.usr_username;
HttpContext.Current.Session["user_group_id"] = obj.UserInfo.UserGroupID;
HttpContext.Current.Session["groupid"] = obj.UserInfo.groupid;
HttpContext.Current.Session["token"] = obj.Token;
HttpContext.Current.Session["web_server_url"] = obj.ServerInfo.web_server_url;
HttpContext.Current.Session["centerX"] = obj.ServerInfo.DefaultGeoX;
HttpContext.Current.Session["centerY"] = obj.ServerInfo.DefaultGeoY;
HttpContext.Current.Session["dateFormat"] = obj.ServerInfo.dateFormat;
HttpContext.Current.Session["currency"] = obj.ServerInfo.currency;
HttpContext.Current.Session["customer_img"] = obj.ServerInfo.customer_img;
HttpContext.Current.Session["groups"] = obj.groups;
HttpContext.Current.Session["restrict_call_type"] = restrict ;
Debug.WriteLine("obj.UserInfo.UserGroupID " + obj.UserInfo.UserGroupID);
Debug.WriteLine("obj.UserInfo.groups " + obj.groups);
//HttpContext.Current.Session["defaultLanguage"] = obj.ServerInfo.defaultLanguage;
HttpCookie cookie = new HttpCookie("Login");
// if remember me checked then user name and password stored in cookie else cookes is expired
if (user.RememberMe)
{
cookie.Values.Add("user_name", obj.UserInfo.usr_username);
cookie.Values.Add("pwd", user.Password);
cookie.Expires = DateTime.Now.AddDays(15);
HttpContext.Current.Response.Cookies.Add(cookie);
}
else
{
cookie.Expires = DateTime.Now.AddDays(-1);
HttpContext.Current.Response.Cookies.Add(cookie);
}
return true;
}
else
{
//ResultCode -5 :Invalid Login ,-1:Database Error ,-2:Server Error ,-3:Invalid Parameter specified ,-4:Invalid Token
return false;
}
}
catch
{
throw;
}
finally
{
url = string.Empty;
callType = string.Empty;
server = string.Empty;
}
}
Okay here after converts pass to MD5 creates a "string content" with the information given.
Then in next line (HttpResponseMessage json_list = ApiCallBL.GetAPIResponse(url, content);) calls the API with the url and content as parameters where it finds if the data exists.
API code:
public static HttpResponseMessage GetAPIResponse(string url, string content)
{
StringBuilder traceLog = null;
HttpContent httpContent = null;
try
{
traceLog = new StringBuilder();
traceLog.AppendLine("Start: BusinessLayer getAPIResponse() Request Data:- " + DateTime.Now + "URL = " + url + "&content = " + httpContent);
using (HttpClient client = new HttpClient())
{
httpContent = new StringContent(content);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
var resp = client.PostAsync(url, httpContent).Result;
Debug.WriteLine("resp: " + resp.Content.ReadAsStringAsync().Result);
traceLog.AppendLine("End: BusinessLayer getAPIResponse() call completed HttpResponseMessage received");
return resp;
}
}
catch
{
throw;
}
finally
{
traceLog = null;
httpContent.Dispose();
url = string.Empty;
content = string.Empty;
}
}
In the following line, console prints the result that I cant understand where it cames from (Debug.WriteLine("resp: " + resp.Content.ReadAsStringAsync().Result);)
Sorry for the confusion , I am in my first job with zero work experience and I am called to learn how this works alone without proper education on ASP.NET from them.
You will not go very far without debbugger. Learn how to debug in Visual Studio (YouTube tutorials might be fastest way). Place debug points along critical points in code (for example moment when client sends and receives response is line var resp = client.PostAsync...) and check variables.
Url for API server is actually defined in the line
url = ConfigurationManager.AppSettings["login_url"].ToString();
ConfigurationManager means Web.config file, check it's appSettings section for login_url entry, there is your url.
Btw, using (HttpClient client = new HttpClient()) is not a good way to use a HttpClient and will lead to port exhaustion. It's ok for small number of requests, but for larger ones you must reuse it, or use HttpClientFactory (for .NET Core).

Lead Ads Testing Tool - Server failure (102)

I'm trying to get Facebook leadgen ad data.
1-)As seen below, facebook sends the data to me successfully and I receive it successfully.
Successful Process img
2-)But the submissions I made on just this page do not come. What could be the reason for this?
Failed Process img
*But only the opinions I made on this page are not coming. What could be the reason for this?
Facebook doesn't even post. As seen in the picture, Server failure (102) information is displayed. What is the reason of this?
3-)The code I received the incoming data
Asp.Net Api Method
public async Task<HttpResponseMessage> Post([FromBody] JsonData data)
{
try
{
dbmanager db = new dbmanager();
db.Jsonkaydetv2(data);
var entry = data.Entry.FirstOrDefault();
var change = entry?.Changes.FirstOrDefault();
if (change == null) return new HttpResponseMessage(HttpStatusCode.BadRequest);
//Generate user access token here https://developers.facebook.com/tools/accesstoken/
const string token = "XXXX";
var leadUrl = $"https://graph.facebook.com/v2.10/{change.Value.LeadGenId}?access_token={token}";
var formUrl = $"https://graph.facebook.com/v2.10/{change.Value.FormId}?access_token={token}";
using (var httpClientLead = new HttpClient())
{
var response = await httpClientLead.GetStringAsync(formUrl);
if (!string.IsNullOrEmpty(response))
{
var jsonObjLead = JsonConvert.DeserializeObject<LeadFormData>(response);
db.JsonkaydetLeadFormData(jsonObjLead);
//jsonObjLead.Name contains the lead ad name
//Jsonkaydet(jsonObjLead.Name+"x");
//If response is valid get the field data
using (var httpClientFields = new HttpClient())
{
var responseFields = await httpClientFields.GetStringAsync(leadUrl);
if (!string.IsNullOrEmpty(responseFields))
{
var jsonObjFields =JsonConvert.DeserializeObject<LeadData(responseFields);
db.JsonkaydetLeadData(jsonObjFields);
//jsonObjFields.FieldData contains the field value
}
}
}
}
return new HttpResponseMessage(HttpStatusCode.OK);
}
catch (Exception ex)
{
Jsonkaydet(ex.ToString());
Trace.WriteLine($"Error-->{ex.Message}");
Trace.WriteLine($"StackTrace-->{ex.StackTrace}");
return new HttpResponseMessage(HttpStatusCode.BadGateway);
}
}

How to request report from c# console application using Telerik REST API

I have Telerik REST API and at client side i'm using html5 report-viewer. Report are generating successfully in a report viwer in html. Now i want to request for the reports from same API through c# console application. I have search but didn't fine any solution. Please suggest me a way how can i request a report using C# console application.
html5 report-viewer Library
Note: I'm very beginner in telerik reporting.
Update 1:
I have manage to send request to the server using this API documentation.
Telerik Document for Getting Report
on Server side i have written the CustomReportResolver . But now its now sending the InstanceId to the console client.
CustomReportResolver
public class CustomReportResolver : IReportResolver
{
public ReportSource Resolve(string reportJsonString)
{
var reportDto = JsonConvert.DeserializeObject<ReportDTO>(reportJsonString);
var connectionStringHandler = new CustomConnectionStringManager(reportDto.CompanyId);
var reportsPath = HttpContext.Current.Server.MapPath($"~/Reports/{reportDto.ReportPath}");
var sourceReportSource = new UriReportSource { Uri = reportsPath + reportDto.ReportName };
// sourceReportSource.Parameters.Add(new Telerik.Reporting.Parameter("companyId", reportDto.CompanyId));
var reportSource = connectionStringHandler.UpdateReportSource(sourceReportSource);
return reportSource;
}
}
Note if i use default ReportResolver self hosted telerik service sending the pdf report to console successfully but if i use CustomReportResolver it's not generating instanceId.
What could be the problem ?
After wasting a lot of time then found a solution how to get PDF(Or any other report format) documents from Telerik Self hosted Web Service. Following are the general steps to be followed.
Get Client Id
Get Instance Id
Get Document Id
Download Document
Below is a step wise code:
static HttpClient client = new HttpClient();
static string reportServerAddress = "http://localhost:60031/";
static string serverREStAPI = reportServerAddress + "api/";
static void Main(string[] args)
{
try
{
Console.WriteLine("Demo started");
RunAsync().Wait();
Console.WriteLine("Demo ended");
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex);
Console.ReadKey();
}
}
static async Task RunAsync()
{
// readFile();
// return;
client.BaseAddress = new Uri(serverREStAPI);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html"));
/*
* Steps To get PDF documents from Telerik Self hosted Web Service
* Step 1) Get Client Id,
* Step 2) Get Instance Id
* Step 3) Get Document Id
* Step 4) Download Document
*
* */
var clientId = await GetClientIdAsync(serverREStAPI + "reports/clients", "clientId");
var instanceId =
await GetInstanceAsync(serverREStAPI + $"reports/clients/{clientId}/instances", "instanceId");
var documentId =
await GetDocumentAsync(serverREStAPI + $"reports/clients/{clientId}/instances/{instanceId}/documents",
"documentId");
await DownloadPDF(serverREStAPI + $"reports/clients/{clientId}/instances/{instanceId}/documents/{documentId}", true);
}
static async Task<string> GetClientIdAsync(string path, string paramName)
{
HttpResponseMessage response = await client.PostAsJsonAsync(path, "");
response.EnsureSuccessStatusCode();
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
dynamic result = serializer.DeserializeObject(response.Content.ReadAsStringAsync().Result);
return result[paramName];
}
static async Task<string> GetInstanceAsync(string path, string paramName)
{
/*
* For Default resolver in Service
* */
var paramterValues = new {CompanyId = 1};
// var data = new { report = "{ \"ReportName\":\"test.trdx\",\"CompanyId\":\"1\"}", parameterValues = "{\"CompanyId\": \"1\"}" };
var data = new
{
report = "{\"ReportName\":\"test.trdx\",\"CompanyId\":\"1\"}",
parameterValues = paramterValues
};
HttpResponseMessage response = await client.PostAsJsonAsync(path, data);
response.EnsureSuccessStatusCode();
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
dynamic result = serializer.DeserializeObject(response.Content.ReadAsStringAsync().Result);
return result[paramName];
}
static async Task<string> GetDocumentAsync(string path, string paramName)
{
var data = new {format = "PDF"}; //PDF,XLS,MHTML
HttpResponseMessage response = await client.PostAsJsonAsync(path, data);
response.EnsureSuccessStatusCode();
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
dynamic result = serializer.DeserializeObject(response.Content.ReadAsStringAsync().Result);
return result[paramName];
}
static async Task DownloadPDF(string path, bool asAttachment)
{
var queryString = "";
// if (asAttachment)
// {
// queryString += "?content-disposition=attachment";
// }
var filePathAndName = #"D:\testing\tet.html";
// File.Create(filePathAndName);
// string filePath = System.IO.Path.Combine(folderName, fileName);
//System.IO.File.WriteAllText(filePathAndName, result);
using (System.Net.WebClient myWebClient = new System.Net.WebClient())
{
await myWebClient.DownloadFileTaskAsync(new Uri(path + queryString), filePathAndName);
}
System.Diagnostics.Process.Start(filePathAndName);
}

how to get the response body in code webtest?

I wrote a webtest that calls a web-service.
I want to get the response body and do some validation on it.
public override IEnumerator<WebTestRequest> GetRequestEnumerator()
{
WebTestRequest request2 = new WebTestRequest("webservice");
request2.Headers.Add("Content-Type", "application/json");
request2.Method = "POST";
request2.Encoding = System.Text.Encoding.GetEncoding("utf-8");
StringHttpBody request2Body = new StringHttpBody();
request2Body.ContentType = "application/json";
request2Body.InsertByteOrderMark = false;
request2Body.BodyString = #"{ <body>}";
request2.Body = request2Body;
WebTestResponse res = new WebTestResponse();
console.WriteLine(res.BodyBytes);
yield return request2;
request2 = null;
}
When i ran the above code i didn't get any response on my console.
How can i get the response body using coded webtest?
There are at least three problems with the code in the question
The code in the question does not perform the request before doing the WriteLine. The two statements WebTestResponse res = new WebTestResponse(); and console.WriteLine(res.BodyBytes); just create a new WebTestResponse object (with all default values) and then try to print part of its contents. The request is issued by the code that calls your GetRequestEnumerator method.
The console object is not defined. The normal console has a first letter uppercase, ie Console.
When a web test executes I am not sure where its "console" output will go. The standard output of a web test is not, as far as I know, a well defined thing.
An easy way to get at the response body is to use the PostRequest method of a WebTestRequestPlugin. For a start
public class BodyContentsDemo : WebTestRequestPlugin
{
public override void PostRequest(object sender, PostRequestEventArgs e)
{
byte[] bb = e.Response.BodyBytes;
string ss = e.Response.BodyString;
e.WebTest.AddCommentToResult(
"BodyBytes is " +
bb == null ? " null"
: bb.Length.ToString() + " bytes");
e.WebTest.AddCommentToResult(
"BodyString is " +
ss == null ? "null"
: ss.Length.ToString() + " chars");
// Use bb or ss.
}
}
Note the use of AddCommentToResult to provide logging information to the web test results log.
Finally I am able to find a solution for last couple of days I was struggling to capture the response text from Web Performance test. Hope this helps
public override IEnumerator GetRequestEnumerator()
{
WebTestRequest request2 = new WebTestRequest("webservice");
request2.Headers.Add("Content-Type", "application/json");
request2.Method = "POST";
request2.Encoding = System.Text.Encoding.GetEncoding("utf-8");
StringHttpBody request2Body = new StringHttpBody();
request2Body.ContentType = "application/json";
request2Body.InsertByteOrderMark = false;
request2Body.BodyString = #"{<body>}";
request2.Body = request2Body;
WebTestResponse res = new WebTestResponse();
console.WriteLine(res.BodyBytes);
yield return request2;
/*This will generate a new string which can be part of your filename when you run performance tests*/
String randomNo = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss").Replace("-", "").Replace(" ", "").Replace(":", "");
/*This will generate a new file each time your WebRequest runs so you know what the server is returning when you perform webtests*/
/*You can use some Json parser if your response is Json and capture and validate the response*/
System.IO.File.WriteAllText(#"C:\Users\XXXX\PerformanceTestRequests\LastResponse" + randomNo+ ".txt", this.LastResponse.BodyString);
request2 = null;
}

Categories