Track any asp.net web services calls from javascript - asp.net

I am writing a control that will warn a user that their session is about to timeout. I can easily track standard postbacks and post packs in update panels, but I'm struggling to see how I can track calls made to any / all web services.
Is there a mechanism for this, or will I have to try and override the Sys.Net.WebRequest invoke code?

There's nothing wrong in replacing the Sys.Net.WebRequest code - just keep a reference to the previous implementation and call it, after tracking the call. Something like this should do the trick:
(function() {
var originalWebRequest = Sys.Net.WebRequest;
Sys.Net.WebRequest = function() {
// track call
//...
// call original WebRequest
return originalWebRequest.apply(this, arguments);
}
})();

In a similar requirement, we wrote a HttpModule. At that point you could have a good control over your request and track your postbacks of webservices. See here for more information about how to write your own httpmodule http://msdn.microsoft.com/en-us/library/aa719858(VS.71).aspx

Related

Fetch API and CasperJS

I am trying to do something very similar to this thread, except that instead of XHR, the web app (written in React) uses the Fetch API to do its asynchronous calls.
Is there an elegant way to intercept/overwrite fetch? Basically I want to see each AJAX call the site is doing and grab the data from there. I could just grab it as shown on the site after the fact, but we all know that JSON is easier than HTML to deal with. The site is STATEFUL, so I cannot just resend the URL.
I tried just writing a wrapper like:
function replaceFetch(){
(function(window, debug){
var _fetch = window.fetch;
window.fetch = function(u, o = {}) {
console.log("This is a test");
return _fetch(u, o);
}
})(window, false);
};
casper.on("page.initialized", function(resource){
this.evaluate(replaceFetch);
});
But I get "Untitled suite" error, and can't find anything I can require() to implement Fetch.
Any thoughts? Thanks!

Asp.net webforms autosave

I understand this may be an elementary question, but I'm new to Asp.net webforms, so please bear with me.
I have a lengthy form on a page that I would like to autosave when users type in a field, or make a selection. The problem is, all I've been able to find online is autosaves that work on a timer. I'd prefer that it saves as the user makes their edits. Also I would like just the individual form element being edited to be sent to the server to avoid sending the entire page back each time.
I've read that I should use a webservice to accomplish this, but since I want to autosave individual items and not the whole form on a timer, how would I set up a webservice to accomplish this? I'm new to webservices I'd like to know what to read up on. Any links are appreciated.
Also, how is the autosave functionality effected when using asp.net validation controls? I've looked around but can't tell if the entire page needs to be valid to make a trip to the server, or if just a single valid item can be sent itself.
Thanks for any help!
If you set AutoPostBack=True on the field, and you add an OnChange event for it (this will vary depending on the type of field the user is interacting with), you can execute a save. Don't call Page.Validate in the methods where you're doing these updates. Call it when you hit the Submit button.
This could cause a LOT of round trips to the server, and it's a lot of code to write and debug.
The Timer approach is one call to one method on a repetitive basis. If you can I'd recommend going with a timer, but sometimes that's not an option.
Generally speaking this is what you'll want to setup on the client-side. Ideally, you will end up with lots of tiny requests which do not require much power on the back-end. This however depends on lots of variables including the database engine you're using.
$(document).ready(function () {
$("input").blur(OnFieldChanged);
});
function OnFieldChanged()
{
var $this = $(this);
var isValid = ValidateField($this);
if (isValid)
{
SaveField($this);
}
}
function SaveField($field)
{
if ($this.val() === $this.prop("oldVal")) return;
var data = {
id: $("idfield").val()
};
data[$field.attr("id")] = $field.val();
$.post({..}).done(function() {
NotifySaved($this);
$this.prop("oldVal", $this.val());
});
}
function ValidateField($field)
{
// Validate the field with your method of choice, manually call Microsoft's client-side validate function or switch to jquery validate.
return true;
}

Using the most recent .NET framework components, how should a client-side timer be implemented in an ASP.NET site?

I'm a very new ASP.NET developer (and web developer at all for that matter.) I want to put together a simple website that has the web server providing a form containing a few controls for setting a timer, and a start button, which when pressed, posts the configuration to the server (for how long the timer is set for.) and also starts the timer in the client, upon expiration, it would also post to the server that this has been done.
If this is easy please explain to me how to go about doing something like this, if this is not easy, or even more so if this is "not a good way to go about this" please explain to me a better architecture or design for this.
As this is a client-side thing, I wouldn't use ASP.NET :) Obviously it still stands for the server-side, anyway:
New ASP.NET MVC project with a single controller, two views, and two corresponding viewmodels.
View has a <form> with the timer <select> or text-box or something.
Controller has an action that receives the POSTed form data and saves it or something, then returns a 303 response to a view that has a hidden field that specifies when the timer should end, this value should be persisted on the server in Session state in case the user refreshes the page. The value should be saved as an absolute UTC date-time value.
The client has a simple client-script that, on page-load, inspects this hidden fields and sets up the timer using setTimeout.
The script also contains a callback function that will be called when the timer reaches its end. This callback function will create and populate a hidden dynamic <form> element which is submitted, causing a POST request to the server with some tag that identifies the client and timer that expired. The server then does another 303 redirect back to the original view, possibly containing a message for the user or something.
This is probably the simplist way using modern techniques and avoiding complexities inherent in using AJAX or external frameworks like jQuery or Mootools. Note my use of 303 redirect instead of returning a HTML repsonse to a POST request - this is for the user's benefit so they never get the browser "Resubmit form?" dialog and also prevents the timer from being reset.
UPDATE:
Why 3xx Responses Are Good:
When a client submits a POST request, the webserver can respond either by returning a response directly, or by doing a 3xx redirect to another page. The problem with providing a response directly is that the content of the response (i.e. the web page) is not "accessible" as far as HTTP is concerned: you cannot retrieve the same content with a GET request. This is why when a user presses F5 or hits Refresh for a POST'd page they get a message-box prompting them (in cryptic language) to resubmit the form, however often if the user resubmits the form they'll end up breaking the application because their data will be processed twice. This is why ASP.NET WebForms, which its heavy reliance on "postback" is being phased out.
Javascript
The code would look something like this:
// bind to this event rather than executing directly because the onload event is only fired after the entire DOM is available. If you run the code immediately then you won't be able to traverse the DOM tree.
window.onload = setUpCallback;
function setUpCallback() {
var hiddenField = document.getElementByID("someHiddenFieldId");
var timeStampEnd = parseInt( hiddenField.value ); // this is the number of miliseconds since 1970-Jan-01 00:00
var timeStampNow = new Date().getTime(); // this also returns a miliseconds-since-1970 value
var timeToEnd = timeStampEnd - timeStampNow;
if( timeToEnd > 0 ) {
window.setTimeout( onTimerEnd, timeToEnd ); // set-up the callback
}
}
function onTimerEnd() {
var form = document.createElement("form");
form.action = "http://mywebsite/uriToSubmitPostTo";
form.method = "post";
document.documentElement.appendChild( form );
var clientField = document.createElement("input");
clientField.type = "hidden";
clientField.name = "someFieldName";
clientField.value = "someValueToIdentifyTheClientOrJustUseSession?";
form.appendChild( clientField );
form.submit();
}

ASP.NET Async Tasks - how to use WebClient.DownloadStringAsync with Page.RegisterAsyncTask

A common task I have to do for a site I work on is the following:
Download data from some third-party API
Process the data in some fashion
Display the results on the page
I was initially using WebClient.DownloadStringAsync and doing my processing on the result. However I was finding that DownloadStringAsync was not respecting the AsyncTimeout parameter, which I sort of expected once I did a little reading about how this works.
I ended up adapting the code from the example on how to use PageAsyncTask to use DownloadString() there - please note, it's the synchronous version. This is probably okay, because the task is now asynchronous. The tasks now properly time out and I can get the data by PreRender() time - and I can easily genericize this and put it on any page I need this functionality.
However I'm just worried it's not 'clean'. The page isn't notified when the task is done like the DownloadStringAsync method would do - I just have to scoop the results (stored in a field in the class) up at the end in my PreRender event.
Is there any way to get the Webclient's Async methods to work with RegisterPageTask, or is a helper class the best I can do?
Notes: No MVC - this is vanilla asp.net 4.0.
If you want an event handler on your Page called when the async task completes, you need only hook one up. To expand on the MSDN "how to" article you linked:
Modify the "SlowTask" class to include an event, like - public event EventHandler Finished;
Call that EventHandler in the "OnEnd" method, like - if (Finished != null)
{
Finished(this, EventArgs.Empty);
}
Register an event handler in your page for SlowTask.Finished, like - mytask.Finished += new EventHandler(mytask_Finished);
Regarding ExecuteRegisteredAsyncTasks() being a blocking call, that's based only on my experience. It's not documented explicitly as such in the MSDN - http://msdn.microsoft.com/en-us/library/system.web.ui.page.executeregisteredasynctasks.aspx
That said, it wouldn't be all that practical for it be anything BUT a blocking call, given that it doesn't return a WaitHandle or similar. If it didn't block the pipeline, the Page would render and be returned to the client before the async task(s) completed, making it a little difficult to get the results of the task back to the client.

Get data from the ajax response

For school, i have to develop a Twitter client with ASP.NET.
In the app, i have a list of tweets with a delete link. This link is created with the helper Ajax.ActionLink() and i specified a callback function for OnSuccess event.
This link is okay : the action is performed, the callback is triggered BUT i can't access data sent in the Ajax response.
The callback receive only one argument. Here is the dump of this object :
>> Sys.Mvc.AjaxContext
$0: 0
$1: null
$2: Sys.Net.XMLHttpExecutor
$3: Sys.Net.WebRequest
$4: null
Where is my responseText ? I know that the response has a content (according to Chrome developer tools) and i really want to access it.
Bonus : can Ajax client automatically parse the response as JSON (the action returns JSON properly with the JSON method) ?
Thanks ! ;)
The deadline of this school project is over.
I used get_data on the response.
I'm quite disappointed by the lack of documentation for this trivial need. Even now i know the way, i can't find that on MSDN… Such a pity. :(
Back to my precious Ruby on Rails, i feel better.
Good day and thanks for your help anyway ! :)
Try calling get_object() on your AjaxContext to get a javascript object or get_data() to get the text. An easier method though is to have your OnSuccess function take an argument which will be the object returned.
public ActionResult ReturnJson()
{
return Json(new { TestMessage = "Hello, world!" }, JsonRequestBehavior.AllowGet);
}
And the view...
<script type="text/javascript">
function AjaxSuccess(obj) {
alert(obj.TestMessage);
}
</script>
#Ajax.ActionLink("Say Hi", "ReturnJson", new AjaxOptions() { OnSuccess = "AjaxSuccess" })
If you want to access the responseText within your code you do not want to use AJAX(Asynchronous JavaScript And XML), you want to use SJAX (Synchronous JavaScript And XML).
When using AJAX your code will not wait for the responseText it will just continue to execute so if you try referencing it later in your code it may not work as it might not have processed yet.
When using SJAX your code will wait for the responseText before continuing to execute.
I don't use ASP.NET so I can't help with the code.
Here is how it is done in JavaScript: JavaScript - AJAX / SJAX - Submit Form Data to a Script

Resources