I am doing a simple Get request with HttpClient. But I am have issues with it aborting before the request is complete. Fiddler shows that it the request should return a 200, but it shows that the request was aborted. It is diffenitally not hitting the default 100s timeout. Is there any hidden setting I am missing?
var new_client = new HttpClient();
var req = await new_client.GetAsync("http://a20.skout.com/support/captchaMobile/?sid=e91af660-0b3d-4c2f-bbdd-249506b9c440");
req.EnsureSuccessStatusCode();
Image of fiddler request. Showing a sucessful 200 status code but aborted by the client.
Update1: use sid to try "36598189-0f2f-45b9-a794-385a5d5e11c8"
Update2: I am also having problem with this url "http://api.recaptcha.net/challenge?k=6Lc2qN8SAAAAAEe8_R2ALF4hu1V_x34nUV1mzW-W"
Update3: So I manage to get a response with new_client.GetAsync("http://a20.skout.com/support/captchaMobile/?sid=e91af660-0b3d-4c2f-bbdd-249506b9c440").Result. I am unsure why that works but not await. I guess it has to be done syncronously. I will leave the question up just incase someone has a more vaild answer.
Related
I have written an asynchronous HttpModule which logs all the request coming to a website.
When the request arrives at the website, the custom http module calls the WebAPI to log the information to the database. .Net 4.5/Visual studio with IIS Express.
////////////Custom HTTP module////////////////////
public class MyHttpLogger : IHttpModule
{
public void Init(HttpApplication httpApplication)
{
EventHandlerTaskAsyncHelper taskAsyncHelper = new EventHandlerTaskAsyncHelper(LogMessage);
httpApplication.AddOnBeginRequestAsync(taskAsyncHelper.BeginEventHandler, taskAsyncHelper.EndEventHandler);
}
private async Task LogMessage(object sender, EventArgs e)
{
var app = (HttpApplication)sender;
var ctx = app.Context;
//use default credentials aka Windows Credentials
HttpClientHandler handler = new HttpClientHandler()
{
UseDefaultCredentials = true
};
using (var client = new HttpClient(handler))
{
client.BaseAddress = new Uri("http://localhost:58836/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var actvity = new Activities() { AppId = "TEST123", ActivityId = 10, CreatedBy = 1 };
await client.PostAsJsonAsync("api/activity", actvity);
}
}
Simplified WebAPI code for “api/activity”.
public async Task<HttpResponseMessage>Post(Activities activity)
{
await Task.Delay(30000);
// Database logging code goes here….
return new HttpResponseMessage(HttpStatusCode.Created);
}
The question is: when the PostAsJsonAsync is getting executed the code stops there. This is correct as the code has to wait. But the calling routine is not getting continued asynchronously as expected and the website response is slower by 30 seconds.
What is wrong with this code? Hooking an async HttpModule should not interfere in the flow of the Http application? Currently when I visit the website the code is getting blocked.
Now, you have to understand the difference between HTTP request and local application. HTTP is totally stateless. Basically you send out a request, the server process it and send back the response. The server does NOT keep any state info about the client, it doesn't have any idea who the client is at all. So in your case, browser sends out a request -> server got it, waited for 30 sec to process it and then sends back result -> browser got the response and this is the point where the browser shows the result. I am assuming what you are trying to do is, browser sends a request, and then you expect the browser to display something and then after 30 sec the server finishes processing and you want to display something else. This is NOT possible to do with await because of the reason mentioned above. What you should do is to write some javascript codes to send out the request with some identifier, and then ask the server every x seconds to see if task{ID} has finished, if so whats the result.
I am developing a Windows Phone 8 app that sends some data to a server which executes it and returns a result. The server can be queried at any time to GET the status of the current execution which could be initializing,running or finished. The output is available only when the execution is in the finished state. The user has the option to check the current status of the execution, by pressing an 'update' button
XAML
<Button Background="{StaticResource PhoneAccentBrush}"
Click="UpdateRunInfo" > Update info</Button>
This is the method
private async void UpdateRunInfo(object sender, RoutedEventArgs e)
{
ExecutionItem clicked = ((sender as Button).DataContext as ExecutionItem);
HttpClientHandler handler = new HttpClientHandler();
handler.Credentials = new NetworkCredential("username", "password");
HttpClient client = new HttpClient(handler);
string Url = "http://somefakeurl.com/server/run/id/status";
string _status = await client.GetStringAsync(Url);
clicked.status = _status;
}
So the problem is that this method work properly only the first time it is called. After that, GetStringAsync() returns the same results as the first call regardless of the actual status of the server.
I have tried this method in a separate Windows Phone project, the result is the same.
To be sure that the server is running correctly I tried again the same C# code this time on a desktop application and it works perfectly fine.
My theory is that because I send the same request multiple times the WP OS is caching the last result and it gives it back to me instead of actually making the GET request to the server.
Why does the HttpClient return a cached status instead of actually getting the status from the server ?
As suggested by the people commenting it was a caching problem.
The suggestion from user L.B. to set client.DefaultRequestHeaders.IfModifiedSince resolved the problem
As already commented, it's a caching problem (simply speaking: your request is cached, so you get the cached response).
Alexei's answer is probably the most used, especially using the current time as query parameter.
Note: guys, please answer, not comment, otherwise the question will remain in "unanswered" status.
I'm using a simple Web API controller to accept a request from a client to process a payment. The Payflow payment request is started in a new task, and I immediately return a status to the client while I wait for the transaction to complete in my task.
However, in testing, if I send two requests back-to-back to my API, the second request will receive a null response from the SubmitTransaction method of the Payflownet API. Why is this happening?
Here is my method which is making the call
private NameValueCollection SubmitTransaction(NameValueCollection pfpParams)
{
string transactionString = GetTransactionString(pfpParams);
string pfpResponse = _pfNetApi.SubmitTransaction(transactionString, PayflowUtility.RequestId);
return HttpUtility.ParseQueryString(pfpResponse);
}
And here is the value of transactionString that I'm passing to the SubmitTransaction method in both cases (dummy credit card info):
ACCT=4111111111111111&EXPDATE=0115&COMMENT1=&COMMENT2=&CVV2=123&NAME=Joshua Dixon&STREET=123 x st&TENDER=C&ZIP=12345&AMT=5.00&TRXTYPE=S&USER=test&PWD=xxxx&PARTNER=Verisign&VENDOR=test
Whenever I send a single request with that string, the response is correct and expected. However, whenever I send two asynchronous requests with that string, if the first hasn't completed, the second response is always null.
OP's co-worker, answering this in case anyone else has this problem.
This seems to be an issue with thread-safety. Though the documentation indicates otherwise, PayflowNETAPI.SubmitTransaction does not seem to be thread-safe. The problem was solved by using a new instance of PayflowNETAPI for each transaction.
I have a scenario where an HttpListener listens for http requests. I created a thread where is called Request method of HttpListenerContext:
while (true)
{
var ctx = listener.GetContext();
HttpListenerRequest req = ctx.Request;
...
ctx.Response.StatusCode = 200;
ctx.Response.StatusDescription = "OK";
ctx.Response.Close();
}
The problem here is that even if i send only one request (for example by telnet) sometimes i see a lot of requests. The listener prefix is http://localhost:9999. The strange thing is that printing remote endpoint of the request i see two or more different end points for each request. Any ideas?
Given an async controller:
public class MyController : AsyncController
{
[NoAsyncTimeout]
public void MyActionAsync() { ... }
public void MyActionCompleted() { ... }
}
Assume MyActionAsync kicks off a process that takes several minutes. If the user now goes to the MyAction action, the browser will wait with the connection open. If the user closes his browser, the connection is closed. Is it possible to detect when that happens on the server (preferably inside the controller)? If so, how? I've tried overriding OnException but that never fires in this scenario.
Note: I do appreciate the helpful answers below, but the key aspect of this question is that I'm using an AsyncController. This means that the HTTP requests are still open (they are long-lived like COMET or BOSH) which means it's a live socket connection. Why can't the server be notified when this live connection is terminated (i.e. "connection reset by peer", the TCP RST packet)?
I realise this question is old, but it turned up frequently in my search for the same answer.
The details below only apply to .Net 4.5
HttpContext.Response.ClientDisconnectedToken is what you want. That will give you a CancellationToken you can pass to your async/await calls.
public async Task<ActionResult> Index()
{
//The Connected Client 'manages' this token.
//HttpContext.Response.ClientDisconnectedToken.IsCancellationRequested will be set to true if the client disconnects
try
{
using (var client = new System.Net.Http.HttpClient())
{
var url = "http://google.com";
var html = await client.GetAsync(url, HttpContext.Response.ClientDisconnectedToken);
}
}
catch (TaskCanceledException e)
{
//The Client has gone
//you can handle this and the request will keep on being processed, but no one is there to see the resonse
}
return View();
}
You can test the snippet above by putting a breakpoint at the start of the function then closing your browser window.
And another snippet, not directly related to your question but useful all the same...
You can also put a hard limit on the amount of time an action can execute for by using the AsyncTimeout attribute. To use this use add an additional parameter of type CancellationToken. This token will allow ASP.Net to time-out the request if execution takes too long.
[AsyncTimeout(500)] //500ms
public async Task<ActionResult> Index(CancellationToken cancel)
{
//ASP.Net manages the cancel token.
//cancel.IsCancellationRequested will be set to true after 500ms
try
{
using (var client = new System.Net.Http.HttpClient())
{
var url = "http://google.com";
var html = await client.GetAsync(url, cancel);
}
}
catch (TaskCanceledException e)
{
//ASP.Net has killed the request
//Yellow Screen Of Death with System.TimeoutException
//the return View() below wont render
}
return View();
}
You can test this one by putting a breakpoint at the start of the function (thus making the request take more than 500ms when the breakpoint is hit) then letting it run out.
Does not Response.IsClientConnected work fairly well for this? I have just now tried out to in my case cancel large file uploads. By that I mean if a client abort their (in my case Ajax) requests I can see that in my Action. I am not saying it is 100% accurate but my small scale testing shows that the client browser aborts the request, and that the Action gets the correct response from IsClientConnected.
It's just as #Darin says. HTTP is a stateless protocol which means that there are no way (by using HTTP) to detect if the client is still there or not. HTTP 1.0 closes the socket after each request, while HTTP/1.1 can keep it open for a while (a keep alive timeout can be set as a header). That a HTTP/1.1 client closes the socket (or the server for that matter) doesn't mean that the client has gone away, just that the socket hasn't been used for a while.
There are something called COMET servers which are used to let client/server continue to "chat" over HTTP. Search for comet here at SO or on the net, there are several implementations available.
For obvious reasons the server cannot be notified that the client has closed his browser. Or that he went to the toilet :-) What you could do is have the client continuously poll the server with AJAX requests at regular interval (window.setInterval) and if the server detects that it is no longer polled it means the client is no longer there.