Progress Updates on Long Process with Javascript - asp.net

I have an asp.net page that calls a dll that will start a long process that updates product information. As the process is running, I want to provide the user with constant updates on which product that process is on and the status of the products. I've been having trouble getting this to work. I add information to a log text file and I was thinking that I'd redirect to a new page and have that page use Javascript to read from the text file every few seconds. My question is has anyone else tried this and does it work fairly well?

I would use Ajax and poll that text file for updates.

Make the long process so that it updates some state about the progress - status, last product processed, etc.
Once started, you might want to update the progress on only say every 50th item processed, to spare resources (you might not, it depends on what you want) on the ASP.NET side.
If the processing is associated with the current session, you might want to put the state in the session. If it is not - e.g. global - put it in some global state.
Then poll the state once in a while through Ajax from javascript, using e.g. JSON and update the UI accordingly.
Make sure you use proper locking when accessing the shared state.
Also, try to keep the state small (store only what is absolutely required to get the data for the js gui).

Rather than outputting the status to a text based log file (or, in addition to using the log file; you can use both), you could output the status to a Database table. For example, structure the table as so:
Queue:
id (Primary Key)
user_id (Foreign Key)
product_id (Foreign Key) //if available
batch_size //total set of products in the batch this message was generated from
batch_remaining //number remaining in this batch
message
So now you have a queue. Now when a user goes on a particular page, you can do one of two things:
Grab some relevant data from the Queue and display it in the header. This will be updated every time the page is refreshed.
Create an AJAX handler that will poll a web service to grab the data at intervals. This way you can have the status update every 15 or 20 seconds, even if the user is on the same page without refreshing.
You can delete the rows from the Queue after they've been sent, or if you want to retain that data, add another column called sent and set it to true once the user has seen that data.

Related

Is an HTTP request considered idempotent if changes a record's last modified time?

Suppose that I have a table called persons and that a request to change any information about a person also updates that record's last_modified column. Would such a request still be considered idempotent? What I'm trying to find out is if auxiliary fields can be exempted from the criteria of idempotence.
If any information is changed on the database after a request (a POST request obviously, you would not alter a person record on a GET request) then it's not indempotent. By definition. Unless you only store stats (like logs).
Here it's not the last_modified column which is important, it's the change any information about a person.
A GET request is indempotent, you can take any uri and put it in an <IMG> in a web page, browsers will load it without asking, it must not alter anything in the database, or in the session (like destroying a session is not indempotent). An indempotent request can be prefetched, can run in any prioity (no need to care about the order of several indempotent queries,none of them can impact the other), etc.

How to store information "per browser tab" in ASP.NET MVC?

In an MVC application I have a two pages process. On the first page we gather information that will allow us to identify which database record to update. On the second page we gather new values used to update this record. In order for this to work, we need a way to persists information between the two pages, including some record id.
I though of two way to do this and both have some problem.
Store the information in the Session object.
This works as long as the user does not open a second browser window or tab. If he does there is a risk that he'll apply the modifications to the wrong record. Suppose he opens tab 1 and complete the first step. Record id 1 is stored in the Session object. The user then open tab 2 and complete the first step. Record id 2 is then stored in the Session object overwriting record id 1. The user then come back to the first tab and complete the second step thinking he is editing record 1, but in fact he will be editing record 2.
Store the information in an hidden field on the page.
This would solve the problem solution 1 has, but it would be trivial for a ill-intentioned user to change the record id to overwrite any record.
While typing this question I just though of a third solution. That is an hybrid of theses two, but I'm not sure it's completely safe. We could store a random id in an hidden field on the page and use this to prefix the key we use to access data in the session object. I think this would work. Could this be exploited as solution 2 could?
Any other good way to securely store data "per tab" instead of "per session"?
Considering way 2 you may check security server side. If a user does not have modification rights on a specific record then server must not save it. Otherwise he/she is modifying a record that has modifications rights on it and does not matter if he/she is doing it by standard UI or hacking under it.
I think you are mixing up two things - authorization and passing data.
If user is authorized to do stuff with "another record", it's not important if he "tempers the hidden", because he is authorized to change another record as well. Nobody is going to do that intentionally. Means - you just need to check if user is authorized to do stuff in every post from the user i.e. in each controller method (and this is normal practice to always validate all user input server-side).
I would suggest you go with "hidden field".
If you want to separate info in different tabs you should use sessionStorage that differs for each open browser tab.
You can set it like this:
sessionStorage.setItem("perTabValue", "true");
Then you can get your value:
var x = sessionStorage.getItem("perTabValue");
if(x === "yourValue"){
//do anithing you want
}

How store, update global variable in ASP.NET

I have an C#/ASP.NET WebForms app. On the master page, I display a value from a database field. For example, like "DEFCON = 3" to let all users know what level we're at (of course, when the value is changed in the database, a user won't pick up the new value until they do a page refresh). But the value will be the same for everyone.
So I'd obviously prefer NOT to have each user's session hit the database on every page load to check for an updated (a round trip for every user, every page seems very inefficient). A global variable seems like the way to go (though I'm not sure the most modern/simplest way to do this yet).
But beyond this is updating the global variable if and when the DEFCON value is changed in the database. How would I trigger the global variable to get updated, especially since the change to the value in the database happens outside of the web app.
Thanks for any thoughts.
Store data in Application variable.Use Ajax to update variable.

Update data controls whenever update occuer in SQL table

my question is very simple .
say , I have a grid or combo box , its databounded with a table in sql server database.
I wish when ever there occur some update in data table it refresh the grid .
I did it already with timer but doesn't it consuming resources by sending request after each time out ?
What are the possibilities in experts opinion to get this job done .
You are going to need to write some sort of Ajax type control that compares the TimeStamp of the last update when the grid loads to an Ajax or web service call that will return the TimeStamp of the last update/insert. If they are not the same, then refresh your grid. All web applications are stateless meaning that they do not retain state from call to call. Real time controls in some way shape or other do something similar in its behavior depending upon the arhcitecture the control is built on.

Limiting records returned by a sqldatasource, using session variable in where clause

I have a web application which has a Sql Server database on the backend. As the site will be rolled out to different clients (or different virtual directories in IIS), each client derivative of the site will use the same backend.
There is an admin page where text on the site can be changed (enter text in a listview, and choose the page to select where that text will show up, and also you can see company-specific details in the other listviews. As this is a shared database, that means a client can see each other's data.
What I am trying to do is store the accountId (a guid returned from the database from login_authenticate), and stick this into session. I then retrieve this on the admin page, and I want to use this value (But it's always 0000-0000 etc), to limit the records returned in the listview.
Is there an example of this? Also, how can I set the default value (this is in the where clause of SqlDataSource), to programatically what the account id is (so I can give me all records = what the current accountid is, or perhaps, what the login is - this is stored in the account table).
Thanks
This is what I tried.
What I am confused about, though, is whether the where clause, when using a session object, is getting an object that I have written the code to retrieve from the session, or an object I have only added but not retrieved. I get the accountID when logging in (verified via stepping in - obviously - or the login will fail).
I will try again with storing the object in session # the login page when I have just retrieved the accountid variable, and then retrieve it on another page.
For some reason I keep getting 0s so I will look at this in my application.
It sounds like your method should be working. I would follow a debugging process:
Check that you are getting the accountID value from the database. Print it on screen immediately after retrieving the value for the first time.
If this is working, store the value in the Session and immediately retrieve it, and check that you are getting the value back.
Create 2 test pages, one where you set the Session variable and another where you retrieve it.
I know this seems really basic, but the failure is being introduced somewhere in the above 3 places. If you can find which step fails, you will be able to fix it.

Resources