ASP.NET Refresh page on timer; query database in between timer - asp.net

'I have a solution in my head, but am unsure if it is possible in ASP.NET. I don't have a lot of experience with timers. My idea is as follows:
'Code Behind
'At the end of the timer(lets say 1 minute)
Dim qry = "SELECT ISNULL(Value, '') FROM Database.Schema.Table WHERE
Column = #Something"
'set up sql connection and execute query
Using sqlcon as new SQLConnection() 'Don't focus on this part
Using sqlcmd = New SQLCommand(sqlcon,qry) 'Don't focus on this part either syntax is probably incorrect
sqlcmd.Parameters.Add("Something", VarChar)
sqlcmd.Parameters("Something").Value = "Row Found"
'Refresh page; assign label control on .aspx page to value of returned query
'SafeToString() is a function that will safely return a string whether the value is some string, DBNULL, Nothing, or ''
lblString.Text = SafeToString(sqlcmd.ExecuteScalar())
End Using
End Using
I want to be able to do this while maintaining scrolls position as well. So I don't interrupt the work/browsing the user is doing.
Thank you all for your input!

Look up Page Methods. JS can call a code-behind method which can return a value to the js method which can then update the page. The code behind method cannot access the page directly, only return a value to the js method.

I had never used WebForms (which I assume this question is about) but regardless I think you're approaching the problem in a wrong way. A page refresh is destructive and distracting, when a page is refreshed the browser has to fetch the page again (this includes all assets and scripts) and re-render the page.
Client-side implementation
So the solution must be implemented at the client side and not require a full page refresh, this can be achieved using Javascript and ajax(from Wikipedia) requests.
In short ajax is a mechanism for issuing additional requests to a web server while the page is loaded and running. That way you can fetch new data in the background without interrupting the user.
When the page loads set up a timeout or an interval:
let intervalId = setInterval(updateFromServer, 1000);
This interval will call updateFromServer every 1 second (1000ms).
Define the function updateFromServer:
function updateFromServer() {
let newData = fetchData();
updateData(newData);
}
This function is call by the interval we've set up and does 2 things: it fetches new data from the server and pushes it to the DOM using updateData.
You can use ajax (for example with jquery) to fetch the data:
function fetchData() {
return $.ajax({
type: "GET",
url: remote_url,
async: false
}).responseText;
}
This is where ajax comes in, the above lines use jquery ajax api to send a GET request to the server at the url remote_url. The browser issues the request and waits for the server to respond.
And finally update the page (again I'm using jquery):
function updateData(newData) {
$('#data-el').text(newData)
}
Again we are using jquery here (you can use pure javascript though) to find an element with the ID data-el and setting its content to newData.

Related

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();
}

WebRequest Async CallBack Code only gets call the first time

I am an absolute beginner on ASP.net (VB.) Please pardon me if the question is too obvious for the experienced members.
I tried to make a simple WebRequest in the async mode in case the target URL takes long to provide the data. In my code below, I just want to see if the callback block (RespCallback) is called correctly every time. If all goes well, lblResult should have the string '123' appended to it every time I click the button which calls the 'GetData' sub.
However, the lblResult only shows 123 after the first click. After the subsequent click, the lblResult only gets appended with '12', as if RespCallback is never called. When I tried to debug this in Visual Studio, the execution actually stepped right into the RespCallback part and the lblResult.Text watch actually shows '123123' but the resulting Web page always shows only '12312'
I am sure I am missing something basic here, but I just don't know what. I was even guessing that it has to do with browser cache (hence the result changes for the second time) but I don't know how to fix that either.
Can someone please help? Thanks in advance.
Jim
Dim myWebRequest As WebRequest
Public Shared allDone As New ManualResetEvent(False)
Private Shared BUFFER_SIZE As Integer = 1024
Public Class RequestState
' This class stores the state of the request
Private Shared BUFFER_SIZE As Integer = 1024
Public requestData As StringBuilder
Public bufferRead() As Byte
Public request As WebRequest
Public response As WebResponse
Public responseStream As Stream
Public Sub New()
bufferRead = New Byte(BUFFER_SIZE) {}
requestData = New StringBuilder("")
request = Nothing
responseStream = Nothing
End Sub ' New
End Class ' RequestState
Public Sub GetData(Sender As Object, Args As System.EventArgs)
lblResult.Text += "1"
myWebRequest = WebRequest.Create(dataURL)
Dim myRequestState As New RequestState()
myRequestState.request = myWebRequest
' Start the asynchronous request.
Dim asyncResult As IAsyncResult = CType(myWebRequest.BeginGetResponse(AddressOf RespCallback, myRequestState), IAsyncResult)
lblResult.Text += "2"
allDone.WaitOne()
End Sub
Private Sub RespCallback(asynchronousResult As IAsyncResult)
lblResult.Text += "3"
allDone.Set()
End Sub
I don't know VB so it's hard to read for me but I'm suspecting GetData is your onClick handler.
First thing that is not right is that you have Shared members. Why your reset event is Shared? It makes all requests use the same object.
Basically Your code with ManualResetEvent won't work because after first allDone.Set(), your object remains set (as long as web application lives). To get "123" every time you should add allDone.Reset() after allDone.WaitOne().
In Your situation web request returns to client before RespCallback is called every time except first call (when your reset event is in non-signaled state).
AutoResetEvent resets automatically. That's why it worked.
But! You can't do this this way. Making your ResetEvent Shared you make all request use the same object. When more than one request will be processed by your application at the same time you will get undetermined behavior.
Remove Shared from your code. Than your code will work (but not asynchronously) without allDone.Reset() and without AutoResetEvent. But it will provide known results (not depending on amount of requests).
About asynchronous call (now that we have code "working"). Well. There is no async request to your web page. allDone.WaitOne() waits until your async webRequest finish. So basically you could just as well do synchronous request.
You need a special pattern for asynchronous web pages. You can read how to do this here.
But i'm not sure it's what you wanted. Do you want your request to be called asynchronously so that it will not use server resources or do you want to display some message to the user (like "Data is being downloaded...") while your web page will remain fully responsible?
If it's the second one you should use AJAX functionality (Like UpdatePanel or using JavaScript directly). You can read about it here.
Couple things to check:
If your label is a fixed width, then it's possible the text is being clipped
If you are using an UpdatePanel, you will need to set its mode to 'Conditional' and call Update() on it in the RespCallback callback method so that the UI gets refreshed with the latest label text value.

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

Asp.Net / Ajax updating update panel automatically how to?

I have an Asp.net page which requires certain sections to be partially updated automatically at an interval of 5 seconds.
I was planning to use the good old Timer control with the AJAX Update Panel for this purpose, but after a bit of reading on this control i found out that it may have some problems especially if,
1) The time difference between the async event performed ( 4 seconds ) by the update panel and the Timer's tick interval ( which is 5 seconds ) are quite small, the update panel will be held up in the async operation all the time.
2) Also, the fact that timer control doesn't work very well with Firefox.
I just wanted to get your opinion as to whether if i should go ahead with the timer and update panel approach, write some custom javascript that does the partial page update or some other strategy altogether.
Personally, I tend to think that the DIY approach is better -- easier to debug and easier to write.
You can use a javascript setInterval for a timer, and every time the function is called, you can initiate an ajax request to your asp.net code-behind to fetch whatever data needs to be updated.
For example, let's say you simply need to, every 5 seconds, update the current time on a page. Let's assume you have a span of ID currentTime on your page, something like:
<asp:Label id="CurrentTime" runat="server" CSSClass="currentTimeLabel" />
In your initial PageLoad event, you set the time:
protected void PageLoad(...)
{
CurrentTime.Text = DateTime.Now.ToString();
}
Now you need to define some javascript on your page that will, every 5 seconds, call the code-behind and get the new date/time value.
Doing this with something like jQuery is very simple:
$(document).ready(function() {
setInterval(5000, updateTime);
});
function updateTime() {
url: "myPage.aspx/SomePageMethod",
success: function(data) {
$(".currentTimeLabel").text(data);
});
}
In ASP.NET, getting the PageMethod to work is the trickiest part (for me, anyway). You need to create a public function in your code-behind with a 'WebMethod' attribute. Something like this:
[WebMethod]
public static string GetCurrentTime()
{
return DateTime.Now.ToSTring();
}
I didn't test any of this code, but the basic premise is sound and should work fine.
Now, this may seem more complicated than using an UpdatePanel, but I find it easier when I know what code is actually running on my page.
If you need to update a series of controls instead of just one control, you can use a more complicated web method that returns xml or json data, and then parse that using javascript.

Resources