ASHX seems run more than one time - asp.net

I have an ashx to do some sync work; it usually takes about 8 minutes. When the sync finishes, an email will be sent to admin. But when I run that ashx in browser, it keeps on loading forever after it finishes, so that admin gets more than one email.
Can anyone give me some information about why this happens?

If the handler is not returning data to the response, maybe the browser is trying to request again until get a successful status. In this case, you may try to response any text just for retrieve success:
context.Response.StatusCode = 200;
context.Response.ContentType = "text/plain";
context.Response.Write(string.Empty);
But, if the handler is returning data to the response and the response status code is successful, you may try to stop the response just after send the e-mail:
context.Response.End();
return;
And, just for check, verify if you are iterating over a loop that calls the mail sending more than one time.

Related

Get a trigger on page visit?

It's so simple yet i can't figure it out.
I would like to write to DB on page visit (without Google Analytics).
I would like to do it on server side.
Since there is no trigger for it, and I redirect all requests to a function, i tried :
exports.contentServer = functions.https.onRequest((request, response) => {
...
...
return response.redirect(url + "?action=" + action )
.then(function(){ // **** error : .then of undefined
//write to DB a visit
Now this will return error since response.redirect will not return a promise. (as Frank said)
I could write to DB before I redirect user, then i make the website slower.
I could do so from client side, which have security problems.
How would I capture and save every page visit ?
In a callable Cloud Function, sending a response to the client is a signal that the request is completely handled, and that Cloud Functions can shut down the contain/use it for other requests.
So there is no way to continue processing after you send the redirect back to the client. You'll either have to perform an additional request from the client, or wait with sending the redirect until you've sent the event to the database.
Note that you won't have to wait for a response from the database, which is how many analytics systems deal with this situation. They send the response, and then trust that the majority if events will make it through.

What happens when there is network request time out during AJAX request to ASP.NET MVC Action

As stated in the title, i would like to know what happens when an AJAX request is sent to a controller action and, during this time, a network timeout happens for a few ms before the request is completed.
Reply from <Server IP>: bytes=32 time=31ms TTL=122
Request timed out
Reply from <Server IP>: bytes=32 time=28ms TTL=122
Considering the timeout happens only for a couple of ms, what effects would this have on my AJAX request?
This is in continuation to a problem we are facing in our application as explained in this SO question and i would like to know if they are somehow related.
I have googled for similar issues but couldn't find anything useful.
Edit: Apart from the impact on AJAX, would it affect the action method's behavior (server)?
Regardless of whether the timeout happens only for a couple of ms or more, the request will fail. The success callback function of your AJAX request will not be executed and the request will end with the execution of complete callback function. By default, all AJAX requests will have a timeout of 0ms (unlimited), but it will hit the default timeout of the browser.
When an AJAX request times out, the error callback function will be invoked. The second argument of this function is a string describing the type of error and in this case, it will have the value timeout. You can handle request timeouts by handling this callback function and by optionally specifying a timeout value (if not specified, works on the default value) in the AJAX request body:
$.ajax({
...
timeout: 5000, //specify the timeout value in milliseconds
error: function(jqXHR, textStatus, errorThrown) {
if(textStatus==="timeout") {
//code to execute when timeout occurs
}
}
});​
Additionally, you can also check if the request has timed out in the complete callback function (in a similar way as shown above) by checking the second argument which is a string and it will have the value timeout if the request was timed out.
Also, note this:
The timeout period starts at the point the $.ajax call is made; if several other requests are in progress and the browser has no connections available, it is possible for a request to time out before it can be sent.
Request timeouts are usually either left at their default or set as a global default using $.ajaxSetup() rather than being overridden for specific requests with the timeout option.
I would suggest you to use an alternative HTTP/s traffic monitoring tool like fiddler to find the mystery behind the second request.
More info: jQuery ajax documentation
The request will "fail", meaning it will enter the onError state of your AJAX request. The status code will then be 0, since there is no response from the server to determine the real status code (eg. 200 OK or 500 Internal Server Error).
In case of time-out your success callback wont execute so you have to write an error callback at the client side to handle such issues.
You have to raise an exception from server side in case of time-out so that it will get back to the client as an error that is the one way you can handle the time-out.

Start a thread as soon as a long post request comes in

I am trying to upload an image. I need to start a synchronising thread as soon as the http request comes in. Presently my Grails code starts only after the entire post data has been received.
The controller is in fact invoked as soon as the request comes in. Only when the image data is fetched from the http request body does the code stall and wait for the upload to finish.

Programmatically POST to ASP type WEBPAGE

I have been toiling over HttpURLConnection and setRequestProperty for 2 days so far and I cannot get this webpage to Post and return the page I desire. This is what I have so far...
...
String data = URLEncoder.encode("acctno", "UTF-8") + "=" + URLEncoder.encode("1991462", "UTF-8");
URL oracle = new URL("http://taxinquiry.princegeorgescountymd.gov");
HttpURLConnection yc = (HttpURLConnection) oracle.openConnection();
yc.setRequestMethod("POST");
yc.setRequestProperty("Content-Type", "text/html; charset=utf-8");
yc.setRequestProperty("Content-Length", "19004");
yc.setRequestProperty("Cache-Control", "private");
yc.setRequestProperty("Set-Cookie", "ASP.NET_SessionId=v5rdm145zv3jm545kdslgz55; path=/");
yc.setRequestProperty("X-AspNet-Version", "1.1.4322");
yc.setRequestProperty("X-Powered-By", "ASP.NET");
yc.setRequestProperty("Server", "Microsoft-IIS/6.0");
yc.setDoOutput(true);
yc.setDoInput(true);
OutputStreamWriter out = new OutputStreamWriter(yc.getOutputStream());
out.write(data);
out.flush();
//out.write(data);
out.close();
...
It returns the same page defined in URL. it doesn't send me the requested page which should have an ending /taxsummary.aspx
It looks as if the asp takes the post data and generates an HTML unique for each parameter given. How do I give it the correct parameters?
Your code looks fine. I believe it sends POST correctly. I think that the problem is not here. When you are using browser you first perform at least one HTTP GET to arrive to the form. When you are doing this the server creates HTTP session for you and returns its id in response header Set-Cookie. When you are submitting the form using browser it sends this header (Cookie) back, so the server can identify the session.
When you are working from java you are skipping the first phase (HTTP GET). So the first thing you are doing is POST while you do not have session yet. I do not know what is the logic of this ASP page but I think that it just rejects such requests.
So, first check this guess. You can use plugin to Firefox named LiveHttpHeaders. Install it and perform the operation manually. You will see all HTTP requests and responses. Save them. Check that the session ID is sent back from server to client. Now implement exactly the same in java.
BTW often the situation is event more complicated when server sends multiple redirect responses. Int this case you have to follow them. HttpConnection has method setFollowRedirects(). Call it with parameter true.
BTW2: Apache HttpClient is a perfect replacement to HttpConnection. it does everything and is very recommended when you are implementing such tasks.
That's all. Good luck. Sometimes it is not easy...

Why do I get "Cannot redirect after HTTP headers have been sent" when I call Response.Redirect()?

When I call Response.Redirect(someUrl) I get the following HttpException:
Cannot redirect after HTTP headers have been sent.
Why do I get this? And how can I fix this issue?
According to the MSDN documentation for Response.Redirect(string url), it will throw an HttpException when "a redirection is attempted after the HTTP headers have been sent". Since Response.Redirect(string url) uses the Http "Location" response header (http://en.wikipedia.org/wiki/HTTP_headers#Responses), calling it will cause the headers to be sent to the client. This means that if you call it a second time, or if you call it after you've caused the headers to be sent in some other way, you'll get the HttpException.
One way to guard against calling Response.Redirect() multiple times is to check the Response.IsRequestBeingRedirected property (bool) before calling it.
// Causes headers to be sent to the client (Http "Location" response header)
Response.Redirect("http://www.stackoverflow.com");
if (!Response.IsRequestBeingRedirected)
// Will not be called
Response.Redirect("http://www.google.com");
Once you send any content at all to the client, the HTTP headers have already been sent. A Response.Redirect() call works by sending special information in the headers that make the browser ask for a different URL.
Since the headers were already sent, asp.net can't do what you want (modify the headers)
You can get around this by a) either doing the Redirect before you do anything else, or b) try using Response.Buffer = true before you do anything else, to make sure that no output is sent to the client until the whole page is done executing.
A Redirect can only happen if the first line in an HTTP message is "HTTP/1.x 3xx Redirect Reason".
If you already called Response.Write() or set some headers, it'll be too late for a redirect. You can try calling Response.Headers.Clear() before the Redirect to see if that helps.
Just check if you have set the buffering option to false (by default its true). For response.redirect to work,
Buffering should be true,
you should not have sent more data using response.write which exceeds the default buffer size (in which case it will flush itself causing the headers to be sent) therefore disallowing you to redirect.
Using
return RedirectPermanent(myUrl) worked for me
You can also use below mentioned code
Response.Write("<script type='text/javascript'>"); Response.Write("window.location = '" + redirect url + "'</script>");Response.Flush();
There is one simple answer for this:
You have been output something else, like text, or anything related to output from your page before you send your header. This affect why you get that error.
Just check your code for posible output or you can put the header on top of your method so it will be send first.
If you are trying to redirect after the headers have been sent (if, for instance, you are doing an error redirect from a partially-generated page), you can send some client Javascript (location.replace or location.href, etc.) to redirect to whatever URL you want. Of course, that depends on what HTML has already been sent down.
My Issue got resolved by adding the Exception Handler to handle
"Cannot redirect after HTTP headers have been sent". this Error as shown below code
catch (System.Threading.ThreadAbortException)
{
// To Handle HTTP Exception "Cannot redirect after HTTP headers have been sent".
}
catch (Exception e)
{//Here you can put your context.response.redirect("page.aspx");}
I solved the problem using:
Response.RedirectToRoute("CultureEnabled", RouteData.Values);
instead of Response.Redirect.
Be sure that you don't use Responses' methods like Response.Flush(); before your redirecting part.
Error
Cannot redirect after HTTP headers have been sent.
System.Web.HttpException (0x80004005): Cannot redirect after HTTP headers have been sent.
Suggestion
If we use asp.net mvc and working on same controller and redirect to different Action then you do not need to write.. Response.Redirect("ActionName","ControllerName"); its better to use only return RedirectToAction("ActionName"); or return View("ViewName");
The redirect function probably works by using the 'refresh' http header (and maybe using a 30X code as well). Once the headers have been sent to the client, there is not way for the server to append that redirect command, its too late.
If you get Cannot redirect after HTTP headers have been sent then try this below code.
HttpContext.Current.Server.ClearError();
// Response.Headers.Clear();
HttpContext.Current.Response.Redirect("/Home/Login",false);
There are 2 ways to fix this:
Just add a return statement after your Response.Redirect(someUrl);
( if the method signature is not "void", you will have to return that "type", of course )
as so:
Response.Redirect("Login.aspx");
return;
Note the return allows the server to perform the redirect...without it, the server wants to continue executing the rest of your code...
Make your Response.Redirect(someUrl) the LAST executed statement in the method that is throwing the exception. Replace your Response.Redirect(someUrl) with a string VARIABLE named "someUrl", and set it to the redirect location... as follows:
//......some code
string someUrl = String.Empty
.....some logic
if (x=y)
{
// comment (original location of Response.Redirect("Login.aspx");)
someUrl = "Login.aspx";
}
......more code
// MOVE your Response.Redirect to HERE (the end of the method):
Response.Redirect(someUrl);
return;

Resources