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

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);
}

Related

Power BI Embedded with Roles, allowing Row Level Security

I have implemented the Microsoft Example for Embed for your customers from Github, which works perfectly. Link
I am now extending it which there are articles showing using both V1 and V2 of the API, both result in the same error:
Operation returned an invalid status code 'BadRequest'
at
Microsoft.PowerBI.Api.ReportsOperations.GenerateTokenInGroupWithHttpMessagesAsync(Guid
groupId, Guid reportId, GenerateTokenRequest requestParameters,
Dictionary`2 customHeaders, CancellationToken cancellationToken)
[HttpGet]
public async Task<string> GetEmbedInfo()
{
try
{
// Validate whether all the required configurations are provided in appsettings.json
string configValidationResult = ConfigValidatorService.ValidateConfig(azureAd, powerBI);
if (configValidationResult != null)
{
HttpContext.Response.StatusCode = 400;
return configValidationResult;
}
EmbedParams embedParams = await pbiEmbedService.GetEmbedParams(new Guid(powerBI.Value.WorkspaceId), new Guid(powerBI.Value.ReportId));
//EmbedParams embedParams = await pbiEmbedService.GetEmbedToken4(new Guid(powerBI.Value.WorkspaceId), new Guid(powerBI.Value.ReportId));
return JsonSerializer.Serialize<EmbedParams>(embedParams);
}
catch (Exception ex)
{
HttpContext.Response.StatusCode = 500;
return ex.Message + "\n\n" + ex.StackTrace;
}
}
The above code is getting called and per the demo.
public async Task<EmbedParams> GetEmbedParams(Guid workspaceId, Guid reportId, [Optional] Guid additionalDatasetId)
{
PowerBIClient pbiClient = this.GetPowerBIClient();
// Get report info
var pbiReport = await pbiClient.Reports.GetReportInGroupAsync(workspaceId, reportId);
//var generateTokenRequestParameters = new GenerateTokenRequest("View", null, identities: new List<EffectiveIdentity> { new EffectiveIdentity(username: "**************", roles: new List<string> { "****", "****" }, datasets: new List<string> { "datasetId" }) });
//var tokenResponse = pbiClient.Reports.GenerateTokenInGroupAsync("groupId", "reportId", generateTokenRequestParameters);
// Create list of datasets
var datasetIds = new List<Guid>();
// Add dataset associated to the report
datasetIds.Add(Guid.Parse(pbiReport.DatasetId));
// Append additional dataset to the list to achieve dynamic binding later
if (additionalDatasetId != Guid.Empty)
{
datasetIds.Add(additionalDatasetId);
}
// Add report data for embedding
var embedReports = new List<EmbedReport>() {
new EmbedReport
{
ReportId = pbiReport.Id, ReportName = pbiReport.Name, EmbedUrl = pbiReport.EmbedUrl
}
};
// Get Embed token multiple resources
var embedToken = await GetEmbedToken4(workspaceId, reportId);
// Capture embed params
var embedParams = new EmbedParams
{
EmbedReport = embedReports,
Type = "Report",
EmbedToken = embedToken
};
return embedParams;
}
The above code is per the demo apart from one line, which is calling the next method:
var embedToken = await GetEmbedToken4(workspaceId, reportId);
public EmbedToken GetEmbedToken(Guid reportId, IList<Guid> datasetIds, [Optional] Guid targetWorkspaceId)
{
PowerBIClient pbiClient = this.GetPowerBIClient();
// Create a request for getting Embed token
// This method works only with new Power BI V2 workspace experience
var tokenRequest = new GenerateTokenRequestV2(
reports: new List<GenerateTokenRequestV2Report>() { new GenerateTokenRequestV2Report(reportId) },
datasets: datasetIds.Select(datasetId => new GenerateTokenRequestV2Dataset(datasetId.ToString())).ToList(),
targetWorkspaces: targetWorkspaceId != Guid.Empty ? new List<GenerateTokenRequestV2TargetWorkspace>() { new GenerateTokenRequestV2TargetWorkspace(targetWorkspaceId) } : null
);
// Generate Embed token
var embedToken = pbiClient.EmbedToken.GenerateToken(tokenRequest);
return embedToken;
}
The above code is per the example with no roles being passed in or EffectiveIdentity. This works.
public async Task<EmbedToken> GetEmbedToken4(Guid workspaceId, Guid reportId, string accessLevel = "view")
{
PowerBIClient pbiClient = this.GetPowerBIClient();
var pbiReport = pbiClient.Reports.GetReportInGroup(workspaceId, reportId);
string dataSet = pbiReport.DatasetId.ToString();
// Generate token request for RDL Report
var generateTokenRequestParameters = new GenerateTokenRequest(
accessLevel: accessLevel,
datasetId: dataSet,
identities: new List<EffectiveIdentity> { new EffectiveIdentity(username: "******", roles: new List<string> { "********" }) }
);
// Generate Embed token
var embedToken = pbiClient.Reports.GenerateTokenInGroup(workspaceId, reportId, generateTokenRequestParameters);
return embedToken;
}
This is the method to return the token with the roles and effective Identity. This results in the error, but no message or helpful feedback.
OK, after much research overnight the Bad Request response does hide an English message which is not show in the browser. The debugger doesn't have the symbols for the part that causes the error, but I found it by using Fiddler proxy when the actual API responded to the request. In my case, if you send an ID to enable RLS, but the version of the report on the server doesn't have it, this doesn't ignore it, it refuses to give a token to anything. From reading many posts, the Bad Request is just a poor error message when the actual response from the API itself (not the package or the example code that the sample uses with it presents). Hope this helps someone in the future.

Duplicate dictionary key on task list

I'm trying to generate a zip file of pdfs asynchronously to speed things up as follows:
var files = new Dictionary<string, byte[]>();
var fileTasks = new List<Task<Library.Models.Helpers.File>>();
foreach (var i in groups)
{
var task = Task.Run(async () =>
{
var fileName = $"{i.Key.Title.Replace('/', '-')} - Records.pdf";
ViewBag.GroupName= i.Key.Title;
var html = await this.RenderViewAsync("~/Views/Report/_UserRecordsReport.cshtml", i.ToList(), true);
return await _fileUtilityService.HtmlToPDF2(html, null, fileName);
});
fileTasks.Add(task);
}
var completedTaskFiles = await Task.WhenAll(fileTasks);
foreach(var item in completedTaskFiles)
{
files.Add($"{item.FileName}", item.FileResult);
}
return _fileUtilityService.GenerateZIP(files);
I'm generating all my html to pdf file tasks and waiting for them to be completed - then trying to synchronously loop through the completed tasks and add them to my dictionary for zipping but I keep getting the following error:
An item with the same key has already been added
There is no duplicate key in the list of items being added.
EDIT - so the current idea is that because its a scoped service, thats why i'm running into thread issues (attached the file utility service for information)
public class FileUtilityService : IFileUtilityService
{
private readonly IHttpClientFactory _clientFactory;
public FileUtilityService(IHttpClientFactory clientFactory)
{
public async Task<byte[]> HtmlToPDF(string html = null, string url = null)
{
try
{
byte[] res = null;
if (html is null && url != null)
{
var client = _clientFactory.CreateClient();
var requestResp = await client.GetAsync(url);
using var sr = new StreamReader(await requestResp.Content.ReadAsStreamAsync());
html = HttpUtility.HtmlDecode(await sr.ReadToEndAsync());
}
using(var ms = new MemoryStream())
{
HtmlConverter.ConvertToPdf(html, ms);
res = ms.ToArray();
}
return res;
}catch(Exception ex)
{
throw ex;
}
}
public async Task<Library.Models.Helpers.File> HtmlToPDF(string html = null, string url = null, string fileName = "")
{
return new Library.Models.Helpers.File() { FileName = fileName, FileResult = await HtmlToPDF(html, url) };
}

Handling Parallel POST to API

I have a API Post method that takes is a string which represents a Bae64 string of bytes from a word document that the API converts to PDF. My test client sends multiple documents, each on its own task, to the API to be converted. The problem is with concurrency and writing the files. I end up with a file in use since the calls are parallel. I have tried a lot of different way to block the conversion process until a document is converted but none of it has worked. Everything works fine if it's jsut a single file being converted but as soon as it's 2 or more, the problem happens. Can anyone guide me in the correct direction to solve this issue?
API:
[HttpPost]
public async Task<SimpleResponse> Post([FromBody]string request)
{
var response = new SimpleResponse();
Task t = Task.Factory.StartNew(async () =>
{
try
{
Converter convert = new Converter();
var result = await convert.CovertDocToPDF(request, WebConfigurationManager.AppSettings["tempDocPath"], WebConfigurationManager.AppSettings["tempPdfPath"]);
response.Result = result;
response.Success = true;
}
catch (Exception ex)
{
response.Exception = ex;
response.Success = false;
response.Errors = new List<string>();
response.Errors.Add(string.Format("{0}, {1}", ex.Message, ex.InnerException?.Message ?? ""));
}
});
t.Wait();
return response;
}
Conversion code
public Task<string> CovertDocToPDF(string blob, string tempDocPath, string tempPdfPath)
{
try
{
// Convert blob back to bytes
byte[] bte = Convert.FromBase64String(blob);
// Process and return blob
return Process(bte, tempDocPath, tempPdfPath);
}
catch (Exception Ex)
{
throw Ex;
}
}
private async Task<string> Process(byte[] bytes, string tempDocPath, string tempPdfPath)
{
try
{
string rs = RandomString(16, true);
tempDocPath = tempDocPath + rs + ".docx";
tempPdfPath = tempPdfPath + rs + ".pdf";
// This is where the problem happens with concurrent calls. I added
// the try catch when the file is in use to generate a new
// filename but the error still happens.
try
{
// Create a temp file
File.WriteAllBytes(tempDocPath, bytes);
}
catch (Exception Ex)
{
rs = RandomString(16, true);
tempDocPath = tempDocPath + rs + ".docx";
tempPdfPath = tempPdfPath + rs + ".pdf";
File.WriteAllBytes(tempDocPath, bytes);
}
word.Application app = new word.Application();
word.Document doc = app.Documents.Open(tempDocPath);
doc.SaveAs2(tempPdfPath, word.WdSaveFormat.wdFormatPDF);
doc.Close();
app.Quit(); // Clean up the word instance.
// Need the bytes to return the blob
byte[] pdfFileBytes = File.ReadAllBytes(tempPdfPath);
// Delete temp files
File.Delete(tempDocPath);
File.Delete(tempPdfPath);
// return blob
return Convert.ToBase64String(pdfFileBytes);
}
catch (Exception Ex)
{
throw Ex;
}
}
Client:
public async void btnConvert_Click(object sender, EventArgs e)
{
var response = await StartConvert();
foreach (SimpleResponse sr in response)
{
if (sr.Success)
{
byte[] bte = Convert.FromBase64String(sr.Result.ToString());
string rs = RandomString(16, true);
string pdfFileName = tempPdfPath + rs + ".pdf";
if (File.Exists(pdfFileName))
{
File.Delete(pdfFileName);
}
System.IO.File.WriteAllBytes(pdfFileName, bte);
}
else
{
}
}
}
private async Task<IEnumerable<SimpleResponse>> StartConvert()
{
var tasks = new List<Task<SimpleResponse>>();
foreach (string s in docPaths)
{
byte[] bte = File.ReadAllBytes(s);
tasks.Add(ConvertDocuments(Convert.ToBase64String(bte)));
}
return (await Task.WhenAll(tasks));
}
private async Task<SimpleResponse> ConvertDocuments(string requests)
{
using (var client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true }))
{
client.BaseAddress = new Uri(BaseApiUrl);
client.DefaultRequestHeaders.Add("Accept", "application/json");
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));//application/json
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, BaseApiUrl + ApiUrl);
var data = JsonConvert.SerializeObject(requests);
request.Content = new StringContent(data, Encoding.UTF8, "application/json");
HttpResponseMessage response1 = await client.PostAsync(BaseApiUrl + ApiUrl, request.Content).ConfigureAwait(false);
var response = JsonConvert.DeserializeObject<SimpleResponse>(await response1.Content.ReadAsStringAsync());
return response;
}
}
Random String Generator
public string RandomString(int size, bool lowerCase = false)
{
var builder = new StringBuilder(size);
// Unicode/ASCII Letters are divided into two blocks
// (Letters 65–90 / 97–122):
// The first group containing the uppercase letters and
// the second group containing the lowercase.
// char is a single Unicode character
char offset = lowerCase ? 'a' : 'A';
const int lettersOffset = 26; // A...Z or a..z: length = 26
for (var i = 0; i < size; i++)
{
var #char = (char)_random.Next(offset, offset + lettersOffset);
builder.Append(#char);
}
return lowerCase ? builder.ToString().ToLower() : builder.ToString();
}
First, get rid of Task.Factory.StartNew ... t.Wait() - you don't need an additional task, the root level method is async and your blocking Wait just spoils the benefits of async by blocking synchronously.
Second, like a comment suggested above, the file name random string generator is most likely to be not really random. Either do not supply anything to the seed value of your pseudo-random gen, or use something like Environment.TickCount which should be sufficient for this. Guid.NewGuid() will work too.
Another good option for temp files is Path.GetTempFileName (also generates an empty file for you): https://learn.microsoft.com/en-us/dotnet/api/system.io.path.gettempfilename?view=netstandard-2.0
[HttpPost]
public async Task<SimpleResponse> Post([FromBody]string request)
{
var response = new SimpleResponse();
try
{
...
var result = await convert.CovertDocToPDF(...);
...
}
catch (Exception ex)
{
...
}
return response;
}
Based on your code it seems that you have a "faulty" random string generator for file name (I would say _random.Next is a suspect, possibly some locking and/or "app wide" instance could fix the issue). You can use Guid.NewGuid to create random part of file name (which in theory can have collisions also but in most practical cases should be fine) or Path.GetTempFileName:
var rs = Guid.NewGuid().ToString("N");
tempDocPath = tempDocPath + rs + ".docx";
tempPdfPath = tempPdfPath + rs + ".pdf";

Cosmos DB Azure Table API oData Authentication REST / C#?

I'm trying to access Azure Cosmos DB using Table API.
The challenge is, despite creating SharedKeyLite, server is still returning Unauthorized - seems like SharedKeyLite is not supported or I'm generating the signature or headers wrong.
Here is the code
static readonly string storageAccountName = "accountName";
static readonly string storageAccountKey = "xxxx";
static readonly string uri = "https://accountName.table.cosmosdb.azure.com/Contacts()";
static readonly string utc_date = DateTime.UtcNow.ToString("r");
static void Main(string[] args)
{
Console.WriteLine(GetResult().Result);
}
static async Task<string> GetResult()
{
// Set this to whatever payload you desire. Ours is null because
// we're not passing anything in.
Byte[] requestPayload = null;
var requestDateString = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
var requestUri = new Uri(uri);
DateTime now = DateTime.UtcNow;
//Instantiate the request message with a null payload.
using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri)
{ Content = (requestPayload == null) ? null : new ByteArrayContent(requestPayload) })
{
ConstructHeaders(httpRequestMessage.Headers, requestDateString);
string authorizationHeader = GenerateSharedKeyLite(storageAccountKey, storageAccountName, uri,requestDateString);
httpRequestMessage.Headers.Authorization = new AuthenticationHeaderValue("SharedKeyLite", authorizationHeader);
// Send the request.
using (HttpResponseMessage httpResponseMessage = await new HttpClient().SendAsync(httpRequestMessage))
{
string json = await httpResponseMessage.Content.ReadAsStringAsync();
return json;
}
}
}
These are the headers I"m adding, expansion of ConstructHeaders method.
Refer this link for request parameters
//Construct the headers
static void ConstructHeaders(HttpRequestHeaders headers, string now)
{
headers.Add("x-ms-date", now);
headers.Add("x-ms-version", "2017-04-17");
// If you need any additional headers, add them here before creating
// the authorization header.
headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
if (headers.Contains("DataServiceVersion"))
headers.Remove("DataServiceVersion");
headers.Add("DataServiceVersion", "3.0;NetFx");
if (headers.Contains("MaxDataServiceVersion"))
headers.Remove("MaxDataServiceVersion");
headers.Add("MaxDataServiceVersion", "3.0;NetFx");
}
And this is the method that creates the SharedKeyLite
//Created Shared Key Lite
static string GenerateSharedKeyLite(string accessKey, string account, string url, string date)
{
var uri = new Uri(url);
var canonicalizedResourceString = uri.PathAndQuery;
var queryStart = canonicalizedResourceString.IndexOf('?');
if (queryStart > -1)
{
if (queryStart < canonicalizedResourceString.Length - 1)
{
var path = canonicalizedResourceString.Substring(0, queryStart);
var parameters = HttpUtility.ParseQueryString(canonicalizedResourceString.Substring(queryStart + 1));
var sb = new StringBuilder();
foreach (var keyOri in parameters.Keys)
{
var value = parameters[keyOri];
var key = keyOri.ToLowerInvariant();
sb.Append("\n");
sb.Append(key);
sb.Append(":");
sb.Append(value);
}
canonicalizedResourceString = canonicalizedResourceString + sb.ToString();
}
else
{
canonicalizedResourceString = canonicalizedResourceString.Substring(0, canonicalizedResourceString.Length - 1);
}
}
canonicalizedResourceString = $"/{account}{canonicalizedResourceString}";
var stringToSign = $"{date}\n{canonicalizedResourceString}";
var signedSignature = string.Empty;
using (var hmac = new HMACSHA256(Convert.FromBase64String(accessKey)))
{
var outputBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign));
var signature = Convert.ToBase64String(outputBytes);
return $"{account}:{signature}";
}
}
Any Help? Ideally I want to perform the odata query using simple.odata, but first trying to make this work using HttpClient
Just copy your code and it works on my side. If you haven't modified your code, please make sure your storageAccountName and storageAccountKey are correct.
BTW, in method GenerateSharedKeyLite there's no need to add query parameters to canonicalizedResourceString for entity operation. You only need to add comp if you want to operate component info for table or service. See constructing-the-canonicalized-resource-string.
The query string should include the question mark and the comp parameter (for example, ?comp=metadata). No other parameters should be included on the query string.

Error reusing some async json method on windows phone

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

Categories