.NET page caching but still receive query string - asp.net

Is it possible to cache a page render on an iis web server, but still receive and write query string values (that don't affect output) to the database? So that the page render does not have to wait for the database trip to execute in order to serve the page? If possible, how do I implement?
For example, we track various affiliate and search marketing data via query strings, and in the master page code behind, we write the given query string data to the database. The output of the page doesn't change at all for the user (however we may set a cookie based off the qs parameter).
My understanding is that the page render has to wait for the database trip to fully execute in order to render the page. Is that even true?

Yes in general though it can depend on how one handles the caching.
First, you should move that tracking stuff to where it belongs -- a HttpModule. Page need not concern itself. Second, what you probably want to look into is some sort of fire and forget service call or message queueing. This makes the database write a non-blocking operation rather than a blocking operation.
Some options for making the operation non-blocking:
if you are actually writing to a web service, there is an underappreciated [OperationContract(IsOneWay = true)] decoration. Tells the generated proxy to fire and forget the call, will not wait for a response.
Another option would be to use the Asynchronous ADO.NET bits, especially BeginExecuteNonQuery. If you don't handle the callback this should just execute off your thread.
You could always just spawn a thread and deal with it in a non-blocking manner yourself. Just be real careful about handling errors on this thread -- unhandled exceptions will take out the app domain.

Related

How to run code immediately in some other application

I have two Asp.Net web apps, App 1 and App 2. They both use the same database. I am trying to give command from App 1 and immediately run a bit of code in App 2.
The only way I can think of doing this is by inserting a command in the database and have App 2 poll the database every few minutes. But this means there may be a delay in running the code.
Is there a way to run code in App 2 immediately?
You can fire an HttpRequest from one app to another and the code will run almost immediately.
I don't know what language and platform you're using, so it's hard to give you concrete examples, but here are the outlines:
Create a page in App2. In standard ASP.Net, you can use a handler. In ASP Core, you can use an API controller. Both car return a single value or a full object in JSON or XML. Or you can use a standard page if you like to return HTML. The code behind is what you want to run. The rendered page or return value from the handler or controller is what you want App1 to get back in response.
Then from App1, issue an HttpRequest to that page in App2 and check the response to see how to continue (for example, if the code ran successfully or not).
The HttpRequest is in case you want to make the call from the server side of App1. If you want to make the call from the client side, then you use Ajax instead. In the case of Ajax, you have to pay attention to the security side, because you don't want to allow whoever to call that page from App2 unless it unless the code behind doesn't pose any security risk and doesn't return any sensitive data.
One last idea specific to your scenario, since both apps are using the same database, you can add the required values to the database as you were planning to do, and then issue a simple HttpRequest. This way, you don't need to worry about security or passing a any sensitive info. When App2 receives the request, it checks the database to see if the request was actually made from App1 and then processes it, otherwise ignores it.

Concurrent page processing/serving

I've created web application that has a sub that builds a contacts list. This sub fetches phone numbers and email address from a contacts db based on ids that are provided by a user. At it's fastest, the application will process about four ids per second. With 200-300 ids at any given time, the completion time is long.
Time is not really the problem, it's end user status updates. I've created a very crude web service that reads the "CurrentRecordNumber" that is stored in a session variable as the app loops through the ids. I intend to use javascript to call the webmethod from the app periodically to update status.
My problem is that when debugging, the webmethod call will complete successfully, but not until the app is finished processing.
This seems like a very simple problem. I must not be using the right terms because my results seem overly complicated.
I'm very new to asynchronous features of ASP.NET so please forgive. I have, however, written some Winforms that incorporate multiple threads so I have a basic understanding of threading.
This is due to the way ASP.NET treats session. You haven't said whether you are using webforms or MVC, but MVC has a quick workaround for this.
First, the problem:
SessionState is designed to be accessed by one request at a time, in the order received by the server. Think of this as a queue at the bank with only one bank teller available. The first person in line is the first to be helped (though this is on a per-session basis, not a per-user).
ASP.NET locks all other requests that require SessionState from executing until the previous one is done.
I haven't tried to correct this problem in web forms, but the easiest way I know of would be to not require SessionState on your progress check.
In MVC, there's a SessionState attribute that can be applied to the controller or method, indicating that there's no chance of a call to that method overwriting SessionState. As long as your call is read-only, you can make your controller code use this attribute to allow multiple async requests simultaneously:
<SessionState(SessionStateBehavior.ReadOnly)>
Public Class MyController

Securing web method on a public web app

I have a public web app that calls ASP.NET web method in an ASMX file, located in the same site folder in IIS. But, to prevent bots to ping the service directly, we'd like to secure the API so that only our HTML 5 client page can access it. Do you have a suggestion on how should I implement this kind of thing ? Not too much, just a simple mechanism that won't take a week of testing please. Doesn't have to be a 100% full proof method since it is public data and the API just pumps data out, not inserting anything. Just something to limit possibilities of DDOS attack on the API.
The way I've tackled this in the past is with a custom header.
Essentially if your web page is using some form of AJAX call to call back to your services layer, then you can use something like:
xhr.setRequestHeader('custom-header', 'value');
where 'xhr' is an XML Http request that you've built in Javascript
of course you could also take the much easier route of just adding a parameter to your calls query string, EG:
in your ajax call, request:
http://my.services/service.asmx?somesecretkey=foobar
instead of just
http://my.services/service.asmx
Then you can just use the request's query string collection server side to see if it's present or not, and refuse the connection if it's not.
You could even go so far as providing some seed value in the data passed to the page in the first place, then use that seed value to create a unique value (one the server can also calculate) that is returned back in your request to the server.
Doing it that way would provide a slightly higher level of security, as the values would be semi random and not easy for a bot to guess.
Bear in mind also, that if you control the calling page, and you are doing this by ajax, you can also put this key in your post variables collection too so it doesn't have to be visible in the get request.

How to invoke Web service after inserting a raw in a table

I have a program in which it insert a raw in a table after certain operations. I wan to call a web service in code behind to do some special tasks by the using of info that there is in the inserted row.
How I can do that?
Is it good idea to invoke this web service from a stored procedure or not? What are the other options?
More Details: Actually, I have an operation in my web application that take a long time to be completed and it is seriously time consuming operation. I don't want client wait until this process finish. That is why I decide write a web service to do this process in the background.
Therefore, I think it may be a good idea that when client request receive I insert his request in a table and call a web service to handle it. Moreover, I do not want to wait until web service return the result, so I will aware client from its result through the report. I do not know what is the best solution to handle it.
I usually keep myself far away from table triggers(it sounds like you're about to use an on insert trigger for a table).
I don't know your specific situation but you could either :
Call the webservice before or after you call the stored procedure, this way the data layer(stored proc) only handles data and nothing more. You're logical layer will handle the logic of calling an extra webservice.
Write a service that will periodicly read a table and notify the webservice of the latest modifications. More messy but it resembles more the effect you're trying to achieve.
There are probably more solutions but i'd need more information on what it exactly is you're doing. Right now it's kinda vague :)
It is never a good idea to call webservice from Stored procs or other DB objects. You can call it from your code, just after you execute the insert and commit it.
The problem it sounds like is that you cannot guarantee that the web service will be called unless you call it before committing the transaction. However, it sounds like the web service needs to be called after commit. In this case, it sounds like you should use a message queue. You could either build one in your database or you could use one off the shelf (http://aws.amazon.com/sqs/ or http://www.windowsazure.com/en-us/home/features/messaging/).
The steps would be:
Insert message into queue (after this is success you can return the call, depending on what your contract with the caller is)
Read message
Insert into table
Call web service
Delete message
The downside is that you will need to make the operations (inserting into the table and calling the web service) idempotent.

ASP.NET concurrency

I have an ASP.NET application that starts a long running operation during the Event Handler phase in the ASP.NET Page life cycle. This occurs when the end user pushes a button a bunch of queries are made to a database, a bunch of maps are generated, and then a movie is made from jpeg images of the maps. This process can take over a minute to complete.
Here's a link to the application
http://maxim.ucsd.edu/mapmaker/cbeo.aspx
I've tried using a thread from the threadpool, creating and launching my own thread and using AsyncCallback framework. The problem is that the new thread is run under a different userid. I assume the main thread is run under ASPNET, the new thread is run under AD\MAXIM$ where MAXIM is the hostname. I know this because there is an error when it tries to connect to the database.
Why is the new thread under a different userid?
If I can figure out the userid issue, what I'd like to do is check if the movie making process has finished by examining a Session variable in a Page_Load method, then add a link to the page to access the movie.
Does anyone have any good examples of using concurrency in a ASP.NET application that uses or creates threads in an EventHandler callback?
Thanks,
Matt
Did you read this?: http://msdn.microsoft.com/en-us/magazine/cc163725.aspx
Quoting one relevant portion from that link (you should read the whole thing):
A final point to keep in mind as you build asynchronous pages is that you should not launch asynchronous operations that borrow from the same thread pool that ASP.NET uses.
Not addressing the specific problem you asked about, but this is likely to come up soon:
At what point is this video used?
If it's displayed in the page or downloaded by the user, what does the generated html that the browser uses to get the video look like? The browser has to call that video somewhere using a separate http request, and you might do better by creating a separate http handler (*.ashx file) to handle that request, and just writing the url for that handler in your page.
If it's for storage or view elsewhere you should consider just saving the information needed to create the video at this point and deferring the actual work until the video is finally requested.
The problem is that the new thread is run under a different userid. I assume the main thread is run under ASPNET, the new thread is run under AD\MAXIM$ where MAXIM is the hostname.
ASPNET is a local account, when the request travels over a network it will use the computer's credentials (AD\MAXIM$).
What may be happening, is that you're running under impersonation in the request - and without in the ThreadPool. If that's the case, you might be able to store the current WindowsIdentity for the request, and then impersonate that identity in the ThreadPool.
Or, just let the ThreadPool hit the DB with Sql Authentication (username and password).

Resources