I have the following code:
ProgressMessageHandler progress = new ProgressMessageHandler();
progress.HttpSendProgress += new EventHandler<HttpProgressEventArgs>(HttpSendProgress);
HttpRequestMessage message = new HttpRequestMessage();
message.Method = HttpMethod.Post;
message.Content = content;
message.RequestUri = new Uri("http://myaddress");
var client = HttpClientFactory.Create(progress);
sending = client.SendAsync(message);
private void HttpSendProgress(object sender, HttpProgressEventArgs e)
{
//....
}
I want to catch a situation, when "myaddress" is not available. Method HttpSendProgress is called when progress is active, so, I can't check in this method.
Any way to check if "myaddress" is available. I have an idea to start one more thread to check when HttpSendProgress is called last time. But maybe there is a standard method?
I dont think you can check if the address is a working address in the progress event. You need to check the status after the response has come back.
if (response.IsSuccessStatusCode)
{
Console.WriteLine(response.StatusCode.ToString());
}
How to determine a 404 response status when using the HttpClient.GetAsync()
Related
So I'm trying to send a multiform POST to API with http client but it's just hang there indefinetly. I test this code in console and it worked as it should, but then I try to run it like this for the UI
private static async Task<string> ApiTask(...)
{
var SourceStream = File.Open(imgpath,FileMode.Open);
var FileStreamContent = new StreamContent(SourceStream);
FileStreamContent.Headers.ContentType = MediaTypeHeaderValue.Parse("image/jpeg");
var client = new HttpClient();
using (var formData = new MultipartFormDataContent())
{
formData.Add(new StringContent("this is a test"),"comment");
formData.Add(new StringContent("Command: detect"),"message");
formData.Add(fileStreamContent, "image","image.jpg");
var response = await client.PostAsync(url,formData).ConfigureAwait(false);
var responseString = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
return responseString
}
}
And I'm calling it from the EventHandler
public async void buttnclck(object sender, EventArgs e)
{
var task = await ApiTask(...);
lblresult.Text = task;
}
but as I said the code just stay in de .PostAsync line indefinetly or when a System.Threading.Task.TaskCanceledException is thrown.
So what I missing here? I thing I was handeling the async/await methods just fine but it's clear I'm not. I tried also with .Result but it won't work even and would throw System.AggregateException. So please help, been trying to make it work modifying the code as other suggested responses but still not working
EDIT:
after couple of hours debugging and searching I find out my problem relies in formData.Add(FileStreamContent, "image","image.jpg"); maybe I'm not serializing the image correctly? How can I fix this??
I have an android app in Xamarin native. I am trying to consume a Restful service from an API in another server.
I have this:
private async Task<string> CreateCellphone(string url, Cellphone cell)
{
string cellphone = JsonConvert.SerializeObject(cell);
HttpContent content = new StringContent(cellphone, Encoding.UTF8, "application/json");
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.PostAsync(url, content);
string responseMessage = await response.Content.ReadAsStringAsync();
return responseMessage;
}
}
I execute this on a button call like this:
private void RegisterButtonOnClick(object sender, EventArgs e)
{
// Create new GUID
Guid obj = Guid.NewGuid();
// Store the created GUID in a private shared preferences file
var localGUID = Application.Context.GetSharedPreferences("LocalSetup", FileCreationMode.Private);
var guidEdit = localGUID.Edit();
guidEdit.PutString("GUID", obj.ToString());
guidEdit.PutBoolean("IsRegistered", true);
guidEdit.Commit();
// Create the cellphone record into the database for DB admin to activate
_url = Resources.GetString(Resource.String.cellphone_api_url);
Cellphone cell = new Cellphone();
cell.CellphoneId = obj.ToString();
var response = CreateCellphone(_url, cell);
}
But when my code gets to the postAsync method, nothing happens, it just continues without actually sending the code to the endpoint, I have no idea what I might be doing wrong, because all documentation I have on PostAsync tells me this is how to send json data for a Restful Web api endpoint.
Thank you in advance for any pointers.
You need to await the call to CreateCellphone or nothing will happen because the response Task will get disposed of almost immediately. Not sure if you can make your button click method async in Xamarin, but I would try this:
private async void RegisterButtonOnClick(object sender, EventArgs e)
//^^^^^
//Add this
{
//snip
await CreateCellphone(_url, cell);
}
Failing that, there are various way to call an async method synchronously, check this question.
There is another question about this, but it doesn't have a functioning solution at the end, and the only good answer, for some reason, doesn't work, not for the guy who ask it, not for me either.
This such question is here:
How to post data using HttpClient?
Given the corresponding aclarations, this is the code I have so far:
The methods to call the method who connects with the web server:
private void Button_Click(object sender, System.EventArgs e)
{
//. . . DO SOMETHING . . .
PopulateListView();
//. . . DO SOMETHING ELSE . . .
}
private void PopulateListView()
{
//. . . DO SOMETHING . . .
list = await "http://web.server.url".GetRequest<List<User>>();
//. . . DO SOMETHING ELSE . . .
}
The method than connects with the web server:
public async static Task<T> SendGetRequest<T>(this string url)
{
try
{
var uri = new Uri(url);
HttpClient client = new HttpClient();
//Preparing to have something to read
var formContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("OperationType", "eaf7d94356e7fd39935547f6f15e1c4c234245e4")
});
HttpResponseMessage response = await client.PostAsync(uri, formContent);
#region - - Envio anterior (NO FUNCIONO, SIN USO) - -
//var stringContent = new StringContent("markString");
//var sending = await client.PostAsync(url, stringContent);
//MainActivity.ConsoleData = await client.PostAsync(url, stringContent);
#endregion
//Reading data
//var response = await client.GetAsync(url);
var json = await response.Content.ReadAsStringAsync();
MainActivity.ConsoleData = json.ToString();
return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(json);
}
catch(Exception ex)
{
Console.WriteLine("Error: "+ex.ToString());
return default(T);
}
}
You maybe guessed it, but I'm trying to make a method that send some data (through POST) called "markString" to a web-server than receive it and, depending of the "markString" it returns certain json Objects.
This web server is already working properly (I tested it out with some plug-in, it work like it should)
This method is supposed to send the "markString" and receive the data back so then i can use it in the app.
I'm making a Xamarin Android application.
Also have in mind than I don't have any connection problem at all, in fact the app is sending data in an excellent matter when I try to do it using web client, but I want it to send it using HttpClient.
The problem
The code is not returning anything. Any request for information, clarification, question, constructive comments or anything than can lead to an answer would be greatly appreciated too.
Thanks in advance.
Most deadlock scenarios with asynchronous code are due to blocking further up the call stack.
By default await captures a "context" (in this case, a UI context), and resumes executing in that context. So, if you call an async method and the block on the task (e.g., GetAwaiter().GetResult(), Wait(), or Result), then the UI thread is blocked, which prevents the async method from resuming and completing.
void Main()
{
var test = SendGetRequest("http://www.google.com");
test.Dump();
}
public async static Task<string> SendGetRequest(string url)
{
try
{
var uri = new Uri(url);
HttpClient client = new HttpClient();
//Preparing to have something to read
var formContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("OperationType", "eaf7d94356e7fd39935547f6f15e1c4c234245e4")
});
HttpResponseMessage response = await client.PostAsync(uri, formContent);
#region - - Envio anterior (NO FUNCIONO, SIN USO) - -
//var stringContent = new StringContent("markString");
//var sending = await client.PostAsync(url, stringContent);
//MainActivity.ConsoleData = await client.PostAsync(url, stringContent);
#endregion
//Reading data
//var response = await client.GetAsync(url);
var json = await response.Content.ReadAsStringAsync();
return json;
}
catch (System.Exception ex)
{
Console.WriteLine("Error: " + ex.ToString());
return string.Empty;
}
}
There is a classic asp application which makes calls to .shtml files using AspHttp.Conn. It makes the request by appending all the input and also reads the response by reading the values in the response by length.
Here is the example
strMessage= "test.shtml"
Set HttpObj = Server.CreateObject("AspHTTP.Conn")
HttpObj.Url = url & strMessage
HttpObj.PostData = "testarea=" & strRequestData
HttpObj.TimeOut = 60
HttpObj.RequestMethod = "post"
strResponseData = HttpObj.GetURL
Response.Write Mid(strResponseData,3,1)
Response.Write Mid(strResponseData,4,3)
If I need to rewrite this, what will be the best way to do this. I will be using MVC and will be rewriting the UI. what will be the best approach to make httpcall from c#?. The backend to which the request will be sent will not be changed. Please suggest.
Using .Net Framework 4.5 you can make request as
public static async Task<int> HtmlLoadAsync(string url/*, bool addUserAgent = false*/)
{
try
{
var client = new HttpClient();
//if (addUserAgent) OPTIONAL
//{
// client.DefaultRequestHeaders.UserAgent.ParseAdd(UserAgent);
//}
//client.Timeout = TimeOut;
var response = client.GetStringAsync(url); //here you can change client method according to your required outpu
var urlContents = await response;
// process urlContents now
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return 0;
}
Now call it as
private async void Process()
{
await HtmlLoadAsync("http://....");
}
Note: You must have to add reference System.Net.Http
I have a application that uses the SharePoint 2010 REST API.
In the process of creating an Item there are multiple request done after each other:
1 Call: Getting Items from List: Succes
2 Call: Create Item: 401 Unauthorized
This is the same if I do it like this:
1 Call: Create Item: Succes
2 Call: Delete Item: 401 Unauthorized
What I know is that my functions work separately they DON'T work when they are called after each other.
When I close the application (Windows Phone 8.1 app) after creating a item and when restarted try to delete the item it works.
First I thought it had to do with the way I handle my fields so I changed them to NULL in a finally statement but that didn't work.
public async Task<bool> CreateNewItem(NewItem myNewItem)
{
try
{
StatusBar statusBar = await MyStatusBar.ShowStatusBar("Creating new List Item.");
//Retrieving Settings from Saved file
mySettings = await MyCredentials.GetMySettings();
myCred = new NetworkCredential(mySettings.UserName, mySettings.Password, mySettings.Domain);
using (var handler = new HttpClientHandler { Credentials = myCred })
{
HttpClient client = new HttpClient(handler);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
NewItem newItem = myNewItem;
var jsonObject = JsonConvert.SerializeObject(newItem);
HttpResponseMessage response = await client.PostAsync(new Uri(baseUrl + listNameHourRegistration), new StringContent(jsonObject.ToString(), Encoding.Unicode, "application/json"));
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
response.EnsureSuccessStatusCode();
string responseMessage = await response.Content.ReadAsStringAsync();
client.Dispose();
if (responseMessage.Length > 0)
return true;
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
return false;
}
finally
{
request = null;
response = null;
myCred = null;
mySettings = null;
}
return false;
}
Just run into the same problem.
Anyway, the 2nd request does not follow the same authentication procedure. Even if you initialize a new HttpClient object. I sniffed the HTTP traffic.
After the 1st request I am doing another with different credentials. This is also ending in a 401. I am really confused...
Seems the NTLM Handshake stucks at the 2nd of 6 steps
http://www.innovation.ch/personal/ronald/ntlm.html
Edit:
You may want to use the CSOM.
http://social.msdn.microsoft.com/Forums/office/en-US/efd12f11-cdb3-4b28-a9e0-32bfab71a419/windows-phone-81-sdk-for-sharepoint-csom?forum=sharepointdevelopment
While I still don't know what the actual problem is, at least I found a workaround: Use the WebRequest class instead of HttpClient.
I was running into this same error when I realized I was adding the headers each time I was calling the endpoint. Hopefully this will help someone.
Instead I initialized the HttpClient instance in my class constructor and set the headers there. Also I learned it is better practice to only use 1 instance instead of recreating with "using" (See this article https://www.aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/)
I'm invoking CallApiAsync from another class in a loop.
Here's my final solution:
class ApiShared
{
private HttpClient client;
public ApiShared() {
client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", ConfigurationManager.AppSettings["ApiKey"]);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
public async Task<ApiResponse_Root> CallApiAsync(string endpoint)
{
// Make API call
Uri endpointUri = new Uri(endpoint);
var stringTask = client.GetStringAsync(endpointUri);
var data = JsonConvert.DeserializeObject<ApiResponse_Root>(await stringTask);
return data;
}
}
On a windows machine you can resolve this with this registry setting change:
Go to the following Registry entry:
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
Now add a new DWORD to the Lsa folder called: DisableLoopBackCheck and set this to 1
I see that this question has been posted long back. But I don't see a correctly working solution posted yet to this thread.
I faced exactly the same issue where the next requests kept on failing returning me 401 UnAuthorized.
I figured out using fiddler that from SECOND request onwards, there was a Cookie added to the request which was possibly a result of Set-Cookie response sent by the server along with first response.
So here's how I tackled the situation - Make UseCookies false:
new HttpClientHandler { Credentials = myCred, UseCookies = false }
This should resolve your issue. Hope this helps someone who's looking for a solution to a similar issue.