I have the following code. The async call never returns anything. Even for google.com.
try
{
using (
var client = new HttpClient()) {
var response = client.GetAsync("http://www.google.com");
Debug.WriteLine("Coming here1"+response.Result.IsSuccessStatusCode);
if (response.Result.IsSuccessStatusCode)
{
// by calling .Result you are performing a synchronous call
Debug.WriteLine("Coming here1");
var responseContent = response.Result.Content;
// by calling .Result you are synchronously reading the result
string responseString = responseContent.ReadAsStringAsync().Result;
//Console.WriteLine(responseString);
}
else { Debug.WriteLine("else"); }
}
}
catch(Exception e)
{
Debug.WriteLine(e.ToString());
}
}
Try This
try{
WebClient wc = new WebClient();
wc.DownloadStringCompleted+= (sender,args) => {
Debug.WriteLine(args.results);
};
wc.DownloadStringAsync(new Uri(#"http://www.Google.com",UriKind.RelativeOrAbsolute));
}
catch(Exception e){ Debug.WriteLine(e.Message); }
You don't appear to be awaiting your Async call.
Try changing var response = client.GetAsync("http://www.google.com"); to var response = await client.GetAsync("http://www.google.com");
Remember to mark your method as async.
you're also blocking on your async call ReadAsStringAsync().Result. As with client.GetAsync, make sure to await the call instead of blocking with Result. This blog post speaks a bit on the topic.
Read up a bit on async/await. You'll love it once you get the hang of it.
Related
I'm learning Blazor.
I have created a Blazor WASM App with the "ASP.NET Core Hosted" option.
So I have 3 projects in the solution: Client, Server and Shared.
The following code is in the Client project and works perfectly when the endpoint is correct (obviously). But at some point I made a mistake and messed up the request URI, and then I noticed that the API returned an HTML page with code 200 OK (as you can see in the Postman screenshot below the code).
I expected one of my try-catches to get this, but the debugger jumps to the last line (return null) without throwing an exception.
My first question is why?
My second question is how can I catch this?
I know fixing the endpoint fixes everything, but would be nice to have a catch that alerts me when I have mistyped an URI.
Thanks.
private readonly HttpClient _httpClient;
public async Task<List<Collaborator>> GetCollaborators()
{
string requestUri = "api/non-existent-endpoint";
try
{
var response = await _httpClient.GetFromJsonAsync<CollaboratorsResponse>(requestUri);
if (response == null)
{
// It never enters here. Jumps to the last line of code.
}
return response.Collaborators;
}
catch (HttpRequestException)
{
Console.WriteLine("An error occurred.");
}
catch (NotSupportedException)
{
Console.WriteLine("The content type is not supported.");
}
catch (JsonException)
{
Console.WriteLine("Invalid JSON.");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return null;
}
it is a never good idea to use GetFromJsonAsync, You are not the first who are asking about the strange behavior. Try to use GetAsync. at least you will now what is going on.
var response = await client.GetAsync(requestUri);
if (response.IsSuccessStatusCode)
{
var stringData = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<CollaboratorsResponse>(stringData);
... your code
}
else
{
var statusCode = response.StatusCode.ToString(); // HERE is your error status code, when you have an error
}
I have several URL similar to https://zkillboard.com/api/stats/solarSystemID/31000007/
I am trying to extract the JSON from the url into an object.
I have been able to get as far as this which returns a Promise, PromiseState: fulfilled and PromiseResults contains an object with the data I am looking for.
async function readJSON(url:string) {
var request = new XMLHttpRequest();
request.open ('get', url, false)
request.send(null)
if (request.status == 200) {
return JSON.parse(request.responseText)
}
}
const systemJSON = readJSON('https://zkillboard.com/api/stats/solarSystemID/31000007/')
console.log(systemJSON)
How can I ensure that my console.log only returns the PromiseResult?
This seems to have fixed it for me, removed the async from the function as well as .responseText in the JSON.parse()
function readJSON(url:string) {
var request = new XMLHttpRequest();
request.open ('get', url, false)
request.send(null)
if (request.status == 200) {
return JSON.parse(request.response)
}
}
const systemJSON = readJSON('https://zkillboard.com/api/stats/solarSystemID/31000007/')
const printJSON = () =>{
console.log(systemJSON)
}
printJSON();
First off, when handling json from an external source I would suggest wrapping it in a try/catch function, to avoid unsuspecting errors.
Secondly I think the issue is that readJSON returns a promise, so you might need to await it.
try {
const json = await readJSON('https://zkillboard.com/api/stats/solarSystemID/31000007/')
const systemJSON = JSON.parse(json);
} catch (error) {
// Woops something happend - see error variable
}
I am trying to call a get REST API from my tvOS application. Following is my code when tap the Button:
async void ButtonClicked(UIButton sender)
{
try
{
HttpClient client = new HttpClient();
var response = await client.GetAsync("rest api url");
if (response.IsSuccessStatusCode)
{
var Response = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
if (!string.IsNullOrWhiteSpace(Response.ToString()))
{
var category = JsonConvert.DeserializeObject<Videos>(Response.ToString());
Debug.WriteLine("count:>>" + category.webContentCategoryList.Count);
}
}
}
catch(Exception e)
{
Debug.WriteLine("Exception:>>"+e);
}
I have installed the system.net.http and newtonsoft.json nuget packages. But when I run the project the application showing Main.cs file like below screenshot:
Am I missing something in this?
UPDATE
I have added breakpoint for the first line inside ButtonClicked function. When I taps the Button, the application showing Main.cs file like above screenshot. It is not hitting the first line of ButtonClicked function.
So the issue is something else, I am not an expert in tvOS applications so I can't figure out. I have uploaded a sample project here.
I have fixed this issue by separating the service call on a new function like below, new function is the async method:
partial void ButtonClicked(UIButton sender)
{
LoadData();
}
async void LoadData()
{
HttpClient client = new HttpClient();
var response = await client.GetAsync("service url");
if (response.IsSuccessStatusCode)
{
var Response = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
if (!string.IsNullOrWhiteSpace(Response.ToString()))
{
var category = JsonConvert.DeserializeObject<Videos>(Response.ToString());
Debug.WriteLine("count:>>" + category.Count);
}
}
}
My XF Thread is here for more details.
In wp8.0 we can store object to IsolatedStorageSettings. wp8.1 object was not storing. Is there any way to store object to wp8.1.
WRITE OBJECT CODE
NewsList = new ObservableCollection<New>(e.News);
var FileName = "News.xml";
DataContractSerializer serializer = new DataContractSerializer(typeof(ObservableCollection<New>));
var localFolder = ApplicationData.Current.LocalFolder;
var file = await localFolder.CreateFileAsync(FileName,CreationCollisionOption.ReplaceExisting);
IRandomAccessStream sessionRandomAccess = await file.OpenAsync(FileAccessMode.ReadWrite);
IOutputStream sessionOutputStream = sessionRandomAccess.GetOutputStreamAt(0);
serializer.WriteObject(sessionOutputStream.AsStreamForWrite(), NewsList);
READ OBJECT CODE
var FileNameNews = "News.xml";
DataContractSerializer serializer = new DataContractSerializer(typeof(ObservableCollection<New>));
var localFolder = ApplicationData.Current.LocalFolder;
var newsFile = await localFolder.GetFileAsync(FileNameNews);
IInputStream sessionInputStream = await newsFile.OpenReadAsync();
newsVM = new NewsViewModel();
NewsVM.NewsList = (ObservableCollection<New>)serializer.ReadObject(sessionInputStream.AsStreamForRead());
im getting error on this link
IInputStream sessionInputStream = await newsFile.OpenReadAsync();
What mistake is there this code??
Thanks
This is how I do it. No using statements. I try to avoid the Stream syntax as much as possible.
Your error is very likely either because of concurrency (accessing the same file at the same time will throw an exception), or because the stream was not closed properly. I think it is the latter.
You do not dispose of your Stream objects properly (learn the using () {} syntax), which means that the stream remains OPEN after you're done writing. That means you hit the concurrency issue the second time you write, because you're trying to access a stream that's already open.
public async Task CreateOrUpdateData(string key, object o)
{
try
{
if (o != null)
{
var sessionFile = await _localFolder.CreateFileAsync(key, CreationCollisionOption.ReplaceExisting);
var outputString = JToken.FromObject(o).ToString();
await FileIO.WriteTextAsync(sessionFile, outputString);
}
}
catch (Exception e)
{
Debug.WriteLine("Encountered exception: {0}", e);
}
}
public async Task<T> GetDataOrDefault<T>(string key, T defaultValue)
{
try
{
T results = defaultValue;
var sessionFile = await _localFolder.CreateFileAsync(key, CreationCollisionOption.OpenIfExists);
var data = await FileIO.ReadTextAsync(sessionFile);
if (!String.IsNullOrWhiteSpace(data))
{
results = JToken.Parse(data).ToObject<T>();
}
return results;
}
catch (Exception e)
{
Debug.WriteLine("Encountered exception: {0}", e);
}
return defaultValue;
}
I am building my first windowsPhone 8.1 application ,the role of my application is to create connection with server to get information from it, so I am writing the code to do this process by sending json-rpc request to server to get some information ,I am successful to get it in first time but when I send the second request I am receiving an empty response with 404 error (page not found).
But when I call the service without https (http only) it works fine regardless how many time I call it !
public async Task<string> GetDataFromServer(string urlToCall, string JSONData,string RR)
{
string UserName = “XXXXXXX”
string Password = "XXX";
using ( var handler = new HttpClientHandler())
{
handler.Credentials = new NetworkCredential(UserName, Password);
HttpClient client = new HttpClient(handler);
HttpResponseMessage response = null;
try
{
response = await client.PostAsync(urlToCall, new StringContent(JSONData.ToString(), Encoding.UTF8, " application/json"));
string res = response.Content.ReadAsStringAsync().Result;
Windows.UI.Popups.MessageDialog g = new Windows.UI.Popups.MessageDialog(res);
await g.ShowAsync();
return res;
}
catch (Exception ex)
{
Windows.UI.Popups.MessageDialog g = new Windows.UI.Popups.MessageDialog("Error is : " + ex.Message);
g.ShowAsync();
return "Error";
}
finally
{
response.Dispose();
client.CancelPendingRequests();
client.Dispose();
handler.Dispose();
}
}
}
Again, when call the URL of service (start with https) on first time I got response with seeked data, but second time I receive an empty response with 404 error (page not found) !!
Any help please
Please try to use this solution.
public async Task<string> SendJSONData3(string urlToCall, string JSONData)
{
string UserName = "XXXXXXXXX";
string Password = "XXXXXXXXX";
var httpWebRequest = (HttpWebRequest)WebRequest.Create(urlToCall);
httpWebRequest.Credentials = new NetworkCredential(UserName, Password);
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(await httpWebRequest.GetRequestStreamAsync()))
{
string json = JSONData;
streamWriter.Write(json);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)await httpWebRequest.GetResponseAsync();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
return result;
}
}
A couple of ideas:
Do not use the .Result property. Just use await instead to avoid deadlocks.
Remove the additional space in front of the media type parameter " application/json"
Enable logging on the webserver and see if the second request arrives on the server.
Get a network trace, for example with Wireshark or Fiddler.
Try puting WebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp); in your initialization code, as proposed in this answer.