Is there conditional caching in ASP.NET? - asp.net

Is there a built-in asp.net way to conditionally serve pages, for example I want the following logic:
If there is a session data I generate
a page, if there is no session data I
serve the cached page.
I am only interested in knowing about a built-in asp.net mechanism for this. If it does not exist I am probably going to simply cache my page manually and decide whether to serve it or not for each request, based on the session data availability.

I don't think there is built-in support (like varyByParam) for generating fresh output for users with Session Data.
As you suggest, I would recommend manually caching the pages. I would probably determine the user's Session state in the PreRequestHandlerExecute event handler in the Global.asax and then maybe set:
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);

At the risk of karmabombing, I really don't like this approach to caching.
For me if a GET request is made, then a server should respond to that in good faith. Caching at a page level should be controlled by http headers because the primary goal is not to get the redundant request at all - you don't want to allocate server/bandwidth resources full stop.
Caching objects which are resources involved in making up a page I can totally get behind, but I can't see great arguments for caching a page wholesale.
Respect the headers.

You might want to look at the substitution control (Link) new in .NET 2.0, however it might not be exactly what you are after.

Related

Cache and outputcache

What is the difference between property Cache and OutputCache directive?
Cache is where you can put data - stuff coming from the database, or as the result of an expensive calculation, for example. Anything in cache should be available to all users.
OutputCache caches HTML - an entire page, or the output from a user control.
I suppose you can make a desition in your deep heart that both of them are different.
Most of time the Cache is used as the data or business result store. So you could only process your business logic or against your DB at the first time. You'll find it's very efficient one the process need much time. You can use it in your layers: data lay, business lay and so on.
OutPutCache: It announce the IIS server, proxy, or client to cache the response result. Especially benefit for the dynamic pages. The server will response the cached result to the client once it requested before.

Stop Direct Page Calls to Ajax Pages

Is there a "clever" way of stopping direct page calls in ASP.NET? (Page functionality, not the page itself)
By clever, I mean not having to add in hashes between pages to stop AJAX pages being called directly. In a nutshell, this is stopping users from accessing the Ajax pages without it coming from one of your websites pages in a legitimate way. I understand that nothing is impossible to break, I am simply interested in seeing what other interesting methods there are.
If not, is there any way that one could do it without using sessions/cookies?
Have a look at this question: Differentiating Between an AJAX Call / Browser Request
The best answer from the above question is to check for a requested-by or custom header.
Ultimately, your web server is receiving requests (including headers) of what the client sends you - all data that can be spoofed. If a user is determined, then any request can look like an AJAX request.
I can't think of an elegant method to prevent this (there are inelegant and probably non-perfect methods whereby you provide a hash of some sort of request counter between ajax and non-ajax requests).
Can I ask why your application is so sensitive to "ajax" pages being called directly? Could you design around this?
You can check the Request headers to see if the call is initiated by AJAX Usually, you should find that x-requested-with has the value XMLHttpRequest. Or in the case of ASP.NET AJAX, check to see if ScriptMAnager.IsInAsyncPostBack == true. However, I'm not sure about preventing the request in the first place.
Have you looked into header authentication? If you only want your app to be able to make ajax calls to certain pages, you can require authentication for those pages...not sure if that helps you or not?
Basic Access Authentication
or the more secure
Digest Access Authentication
Another option would be to append some sort of identifier to your URL query string in your application before requesting the page, and have some sort of authentication method on the server side.
I don't think there is a way to do it without using a session. Even if you use an Http header, it is trivial for someone to create a request with the exact same headers.
Using session with ASP.NET Ajax requests is easy. You may run into some problems, like session expiration, but you should be able to find a solution.
With sessions you will be able to guarantee that only logged-in users can access the Ajax services. When servicing an Ajax request simply test that there is a valid session associated with it. Of course a logged-in user will be able to access the service directly. There is nothing you can do to avoid this.
If you are concerned that a logged-in user may try to contact the service directly in order to steal data, you can add a time limit to the service. For example do not allow the users to access the service more often than one minute at a time (or whatever rate else is needed for the application to work properly).
See what Google and Amazon are doing for their web services. They allow you to contact them directly (even providing APIs to do this), but they impose limits on how many requests you can make.
I do this in PHP by declaring a variable in a file that's included everywhere, and then check if that variable is set in the ajax call file.
This way, you can't directly call the file ever because that variable will never have been defined.
This is the "non-trivial" way, hence it's not too elegant.
The only real idea I can think of is to keep track of every link. (as in everything does a postback and then a response.redirect). In this way you could keep a static List<> or something of IP addresses(and possible browser ID and such) that say which pages are allowed to be accessed at the moment from that visitor.. along with a time out for them and such to keep them from going straight to a page 3 days from now.
I recommend rethinking your design to be sure that this is really needed though. And also note IPs and such can be spoofed.
Also if you follow this route be sure to read up about when static variables get disposed and such. You wouldn't want one of those annoying "your session has expired" messages when they have been using the site for 10 minutes.

asp.net server side viewstate without sessions

So I've done my best to minimize my viewstate on my ASP.net ajax application, http compression, disabling viewstate in hidden fields, but would like to go further. So after researching it seems that there are two approaches
a) use the ASP.net 1.x way which uses LoadPageStateFromPersistenceMedium
b) or use the ASP.net 2.x way SessionPageStatePersister
So B doesn't look good because if I understand it correctly the viewstate would be linked to the session id, and since my session can expire for any number of reasons I want don't want this.
So what's the best approach to saving viewstate on the server that does depend on sessions?
If it's LoadPageStateFromPersistenceMedium and uses hidden fields, then how do I inject a hidden field with a random id into a page?
How do I determine when it's time to clear viewstate files on the server?
I think you should seriously consider the Session option. It's optimal on resources and even if the Session expires if your Auth mechanism is alighed to session timeout it's not an issue.
http://professionalaspnet.com/archive/2006/12/09/Move-the-ViewState-to-Session-and-eliminate-page-bloat.aspx
As a fallback you could implement a Page base that puts the Session ID into the ViewState, checks it on postback and if it's different than does some action to recover.
The only other option you have would be to create your own PageAdapter that uses the DB or some other data store.
How about trying Flesk ViewState Optimizer?
Has several options including storing in session, in database, etc.

Finding the right caching and compression strategy for asp.net

I'm trying to figure out the best way to do caching for a website I'm building. It relies heavily on screen scraping the wikipedia website. Here is the process that I'm currently doing:
User requests a topic from wikipedia via my site (i.e. http://www.wikipedia.org/wiki/Kevin_Bacon would be http://www.wikipediamaze.com/wiki?topic?=Kevin_Bacon) NOTE: Because IIS can't handle requests that end in a '.' I'm forced to use the querystring parameter
Check to see if I've already stored the formatted html in my database and if it does then just display it to the user
Otherwise I perform a web request to wikipedia
Decompress the stream if needed.
Do a bunch of DOM manipulation to get rid of the stuff I don't need (and inject stuff I do need).
Store the html in my database for future requests
Return the html to the browser
Because it relies on screen scraping and DOM manipulation I am trying to keep things speedy so that I only have to do it once per topic instead of for every single request. Here are my questions:
Is there a better way of doing caching or additional things I can do to help performace?
I know asp.net has built in caching mechanism, but will it work in the way that I need it to? I don't want to have to retrieve the html (pretty heavy) from the database on every request, but I DO need to store the html so that every user get's the same page. I only ever want to get the data from Wikipedia 1 time.
Is there anything I can do with compression to get it to the browser quicker and if so can the browser handle uncmopressing and displaying the html? Or is this not even a consideration. The only reason I'm asking is that because some of the pages wikipedia sends me through the HttpWebRequest come through as a gzip stream.
Any and all suggestions, guidance, etc. are much appreciated.
Thanks!
You can try to enable the OutputCache for your page with VaryByParam=topic. That stores a copy of the page in memory if multiple clients request it. When the page is not in memory, the server can retrieve it from your database. The beauty of OutputCache is that you can even store a gzipped version of the HTML (use VaryByEncoding)
If it's a problem for you to decompress the stuff you get from Wikipedia, then don't send an Accept-Encoding header. That should force Wikipedia to send the page to you uncompressed.
Caching strategy: write the HTML to a static file and let users download from that file.
Compression strategy: check out Google's PageSpeed Best Practices.

ASP Classic GET request without multithreading

We are talking about Classic ASP and NOT ASP.NET!
Lets start from top. We are using ISAPI_Rewrite and we would like to dynamically offer our customers to control rewriting of urls (giving them httpd.ini is not an option). We were thinking that all unknown url requests (we define this in httpd.ini) are controlled by one asp file which creates a GET request to select url (customers creates key -> value table). Now, we can make a request to another page and just print the output but we cannot make a request to our own server. As I am aware, ASP doesnt offer this.
We could write a .NET extension to control this but we are looking for other options. I know that declining .NET is a stupid thing, but its a long story...
Is there a solution to this problem in ASP?
Have a look at Server.Execute it allows dynamic (run time) code inclusion of other ASP files. An added bonus is that it's treated as part of the original request so SESSION, COOKIE are all available in the included file. HOWEVER variables defined in the master are not available to the included the page. You circumvent this using temporary Session variables though.
Session("variable") = "value";
Server.Execute(url);
Session.Abandon;
Response.end;
Session.Abandon will clear ALL session variables, you might want to clear them individually.
You can make a request to your own server but the page making the request needs to NOT have session enabled in the page declaration right at the top of the page:
Each page locks the session object and its that which stops you making a request to your own server. If you declare you are not going to use session in the calling script then it wont lock it and you can run it again using a XMLRequest and pass what you like on the querystring, post data and session cookies too so session etc. will all still exist.

Resources