Asp.net webforms HttpClient.PostAsync - Goes to sleep mode - DeadLock - c#

I am using a library for communicate with a crypto api.
In Console Application every thing is ok about async post.
But in webforms it goes to sleep and nothing happens!
Just loading mode.
Here is the method :
private async Task<WebCallResult<T>> PostAsync<T>(string url, object obj = null, CancellationToken cancellationToken = default(CancellationToken))
{
using (var client = GetHttpClient())
{
var data = JsonConvert.SerializeObject(obj ?? new object());
var response = await client.PostAsync($"{url}", new StringContent(data, Encoding.UTF8, "application/json"), cancellationToken);
var content = await response.Content.ReadAsStringAsync();
// Return
return this.EvaluateResponse<T>(response, content);
}
}
private HttpClient GetHttpClient()
{
var handler = new HttpClientHandler()
{
AllowAutoRedirect = false
};
var client = new HttpClient(handler);
client.BaseAddress = new Uri(this.EndpointUrl);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
return client;
}
In line var response = web site goes to loading mode.
No error - Nothing - Just Loading.
How can i fix this problem in webforms?
In Console Application it is working fine.
Maybe i should change something in Web.config!!!
Here is the library

Related

C# async - creating a task properly

I'm creating a Task in C# but I'm not sure what I do is correct. I'm using Restsharp and in Restsharp there are two methods: Execute and ExecuteAsync. I want to do an Async call but I also need to return data to the client without blocking the execution.
Therefore I created a task which will use Execute instead of ExecuteAsync. The reason why is because I have to wait until I get a response back and then return it in the right data structure. So I thought there is no use in using ExecuteAsync if I have to await it in a Task...
My code looks as follows:
public Task<Response> ExecuteAsync()
{
return new Task<Response>(() =>
{
var client = new RestClient(URL);
if (_useBasicAuth)
{
client.Authenticator = new HttpBasicAuthenticator(_username, _password);
}
var request = RequestBuilder(_method);
var response = client.Execute(request);
return new Response()
{
HttpStatusCode = response.StatusCode,
HttpStatusDescription = response.StatusDescription,
Content = response.Content,
Cookies = ExtractCookies(response.Cookies),
Headers = ExtractHeaders(response.Headers)
};
});
}
Is this correct? The client should be able to call ExecuteAsync without blocking the execution.
I strongly suspect you should really just use ExecuteAsync and write an async method:
public async Task<Response> ExecuteAsync()
{
var client = new RestClient(URL);
if (_useBasicAuth)
{
client.Authenticator = new HttpBasicAuthenticator(_username, _password);
}
var request = RequestBuilder(_method);
var response = await client.ExecuteAsync(request).ConfigureAwait(false);
return new Response
{
HttpStatusCode = response.StatusCode,
HttpStatusDescription = response.StatusDescription,
Content = response.Content,
Cookies = ExtractCookies(response.Cookies),
Headers = ExtractHeaders(response.Headers)
};
}

Xamarin Forms - API Post Call not calling

In a Xamarin Form app, from the Master Page menu, in the Portable project, I call Content page InfoScreen into the Detail. InfoScreen code looks something like this:
public InfoScreen()
{
InitializeComponent();
ListAccounts();
}
public void ListAccounts()
{
SearchAccounts SA = new SearchAccounts();
SearchAccountRequest searchAccountRequest = new SearchAccountRequest("000123456789", "","","","");
var searchAccountResult = SA.SearchAccountAsync(searchAccountRequest);
}
Notice that on load it calls ListAccounts, located in a class in the Portable project, which looks as follows:
public async Task<SearchAccountResult> SearchAccountAsync(SearchAccountRequest searchAccountRequest)
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:00/api/");
string jsonData = JsonConvert.SerializeObject(searchAccountRequest);
var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
var response = await client.PostAsync("SearchForAccount", content);
var result = response.Content.ReadAsStringAsync().Result;
if (result != "")
{
var sessionResponseJson = JsonConvert.DeserializeObject<SearchAccountResult>(result);
}
However, when var response = await client.PostAsync("SearchForAccount", content); gets hit, it just goes back to InfoScreen and continues to load. The API is never hit, which I'm running locally on debug mode. I tested with Postman and it's working correctly.
I also tried:
var client = new HttpClient();
var data = JsonConvert.SerializeObject(searchAccountRequest);
var content = new StringContent(data, Encoding.UTF8, "application/json");
var response = await client.PostAsync("http://localhost:00/api/SearchForAccount", content);
if (response.IsSuccessStatusCode)
{
var result = JsonConvert.DeserializeObject<SearchAccountResult>(response.Content.ReadAsStringAsync().Result);
}
else
{
//
}
Same results. What am I missing?
Thanks
===============
Tried calling the DEV server, utilizing IP, works fine from Postman. Only thing I'm getting in the app is
Id = 1, Status = WaitingForActivation, Method = {null}

Error on ConfigureAwait(false)

I am trying to retrieve some data from an API, the following is my piece of code that makes the request after authenticating and assigning the completed URL.
public async Task<T> GetAPIData<T>(string url)
{
using (var client = HttpClientSetup())
{
var response = await client.GetAsync(url).ConfigureAwait(false);
var JsonResponse = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
return JsonConvert.DeserializeObject<T>(JsonResponse);
}
}
private HttpClient HttpClientSetup()
{
var client = new HttpClient { BaseAddress = new Uri(apiBaseUrl) };
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = authenticationHeader;
return client;
}
I am getting an error on the line with ConfigureAwait(false);
as
"HTTPResponseMessage does not contain a definition for ConfigureAwait"
. Could anyone help me as to what might be going wrong?

Windows 8 universal authentication

I have an MVC5 application in which I use Owin to authentiate users,
now I'm trying to create a Windows 8 app for this application. But I can't find the best why to implement authentication. I found two possible solutions "Web Authentication Broker" and "Credential Locker" but I'm not sure yet
using (var client = new HttpClient())
{
HttpResponseMessage response = null;
var requestContent = string.Format("UserLogin={0}&UserPassword={1}", userName, password);
HttpContent content = new StringContent(requestContent);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
Task task = Task.Run(async () =>
{
response = await client.PostAsync(new Uri((string)ApplicationData.Current.LocalSettings.Values["LoginApiUrl"]), content);
});
task.Wait(); // Wait
var responseData = await response.Content.ReadAsStringAsync();
var deserializedResponse = JsonConvert.DeserializeObject<Dictionary<string, string>>(responseData);
if (deserializedResponse.ContainsKey("success") && Convert.ToBoolean(deserializedResponse["success"]))
{
LoadData();
}
}

Windows Phone 8.1 Runtime HttpClient async with the same result

I'm working with Windows Phone Runtime API.
I declare a timer, which every 2 seconds does async http connection in Listen method.
Timer t = new Timer(Listen, null, 0, 2000);
Listen method:
private async void Listen(object state)
{
string url = "http://www.mywebpage.com?data=my_data";
string responseBodyAsText = null;
var response = new HttpResponseMessage();
var httpClient = new HttpClient();
try
{
response = await httpClient.GetAsync(new Uri(url));
responseBodyAsText = await response.Content.ReadAsStringAsync();
}
catch
{
//...
}
Debug.WriteLine(responseBodyAsText);
httpClient.Dispose();
}
My problem is that responseBodyAsText contains always the same data (given the same uri) and not as I would expect different data according to my external actions (modifying web page or different results with the same uri).
Does HttpClient remembers content during liftime of application? How can I solve this problem?
HttpClient does have caching on by default. You can turn it off by passing it an HttpBaseProtocolFilter:
var filter = new HttpBaseProtocolFilter
{
CacheControl.ReadBehavior = HttpCacheReadBehavior.MostRecent,
CacheControl.WriteBehavior = HttpCacheWriteBehavior.NoCache;
}
Side note: You could also, instead of a Timer, use Task.Delay to achieve the timer behavior (it internally uses one):
private async Task ListenAsync()
{
while (someCondition)
{
string url = "http://www.mywebpage.com?data=my_data";
string responseBodyAsText = null;
var response = new HttpResponseMessage();
using (var httpClient = new HttpClient())
{
try
{
response = await httpClient.GetAsync(new Uri(url));
responseBodyAsText = await response.Content.ReadAsStringAsync();
}
catch
{
//...
}
Debug.WriteLine(responseBodyAsText);
await Task.Delay(2000);
}
}

Categories

Resources