Is it possible to cache an asp page on the server side? - asp.net

Let's assume you have a big complex index page, that shows news articles and stuff. It's not going to change very often. Can you cache it somehow on the serverside, so requests don't force to server to dynamically generate the entire page every time someone visits it? Or does ASP.NET do this automatically?
If so, how does it know if something has changed?

Yes you can, here is the declarative version of page caching, which will cache the page for 60 seconds:
You ask about changes, notice the VaryByParam part - you can, for example, ensure that there is one cached page for each parameter. You can even implement your own custom variation with VaryByCuston, which can be really powerful:
VaryByCustom
Any text that represents custom output caching requirements. If this attribute is given a value of browser, the cache is varied by browser name and major version information. If a custom string is entered, you must override the HttpApplication.GetVaryByCustomString
method in your application's Global.asax file.

Yes, caching exists, MSDN discusses it better than I can here. http://msdn.microsoft.com/en-us/library/06bh14hk.aspx

Related

ASP.net output caching

Just a quick question so I full understand this better, the way I understand it currently is if you set a page to be cached the HTML generated is essentially saved and then reserved.
This means no code behind on that page is run until the cache expries and regenerates. Also, if say for example I have a dynamically generated date stamp, this will always be the date the cache was generated.
Is this correct?
Read the artice about caching. If you want to fully understand Http Caching, you should also read Caching In Http. And the answer is yes, once the page is saved in cache, no code behind is run before it's regenerated. Also, dynamically generated content will stay in cached page as static
Yes, but you can flag some portions of code or some controls to be rewrited.
You can catch only some controls or all controls except one...
Catch the data from database or some collections...
Is a lot flexible.

eTag and many versions of page

I have an ASP .NET site with a custom server-side caching system which is a nightmare. I want to use eTags to replace this.
Many of the links in the site return different versions of a page depending on session state for the user. An example - mypage.aspx?p=a will return different versions of mypage - equally valid, depending on session state. I'd like to cache all versions.
Without totally redesigning the navigation links, how can I do this? From what I've read, putting a different eTag on each as they are generated and served for the first time will just cause the last-generated version to be invalidated and dropped from the cache.
Thanks
PS could I use Response.Cache.VaryByHeaders["Content-Length"] = true and rely on each version being different in length?
PPS Stupid idea! What about adding a custom header with a version key to the response and use VaryByHeaders on that.
The problem you have with custom headers is unless the thing at the other end understands them, they won't be reciprocated. So sending custom headers to IE will just result in it ignoring them.
You can use Output Caching though. It's possible to create your own outputcacheprovider. That would let you mess with the cache based on your requirements.
See http://msdn.microsoft.com/en-us/library/hdxfb6cy(VS.90).aspx for details on Output Caching.
It would appear the outputcacheprovider is only .Net 4

Caching a user control and clearing that cache programmatically

I'm trying to cache user controls and on some pages i want to cache single objects. There are multiple ways of implementing caching, and my head is breaking over it.
The way I see the caching options now:
You have the PartialCaching option which is set to cache the control for 30 minutes, and after that it clears itself... You have the varyByParam to identity the page by its querystring paramaters... or other vary options
But i just cant find an appropriate way to add caching to a control, and be able to clear the caching programmatically when i update one of the objects used in the control from the backend.
You can do HttpContext.Current.Cache.Insert(), which accepts a key on which you can destroy the caching item later by using remove... This can save objects in cache but can you use options like varyByParam?
My questions are burnt down to two:
Is there a way to clear the caching on specific user controls from the code? If yes, can this be done according to the varyby options?
How would the object caching respond to logged in users or anonymous users using Insert()?
EDIT:
I'm caching multiple things.... And I'm really flabbergasted in which choice to make referring to caching. Can the Cache.Insert be varied by Parameters?
The main problem is peopling editing things from the backend, which needs to trigger an event that reinstantiates or clears all caching items referring that object.
You can remove items from the output cache using the following.
HttpResponse.RemoveOutputCacheItem("/caching/CacheForever.aspx");
Now, this is only going to get you part of what you are looking for. This will remove ALL cache entries for that specific page. The MSDN documentation confirms the behavior.
As to your other question Cache.Insert() is a single cache store across the application, user identity is not considered.
Now I would also take a bigger look at what you are doing, it might make sense to only cache the actual data and then you can add/remove the specific items. However, if your .control really does take a lot of CPU etc to handle the display then the output cache idea works.
Using the System.Web.Caching.Cache class you can cache items and create dependencies for the items in the cache. If you're using a SQL server, then you can use the SqlCacheDependency class to clear items from your cache based on your database.
Otherwise you can create your own derivatives of the CacheDependency class which you can use to accomplish the same thing. I found this post that describes doing that.

ASP.NET #OuputCache Directive "Inheritance"

As I mention in an earlier question, I am having trouble with the performance of a web site... Some SQL queries are killing the server. But, as the title of this post mention, I looked at the OutputCache page directive to improve performance of the site.
Although, I came across some questions regarding this directive:
1- If I have a web-user control that declares an OuputCache directive in a page that has one too, which one will "win" ?
2- What's the best pratice regarding the duration ? I'd love to have a sliding window too.
Thanks for your help and please visit http://www.developerit.com
On a request where neither are cached, both the page and the control will be created, and then added to the output cache. If the page is cached, the control will not be created, regardless of whether it's in the cache or not--its markup is contained in the cached copy of the page. If the page is not cached and the control is, the cached markup of the control will be used in the page.
Here's a good article on Output caching: https://web.archive.org/web/20211020111708/https://www.4guysfromrolla.com/articles/121306-1.aspx.
Generally, you seem to be looking at Page and Fragment caching. What you want to do is cache the Page, if you can, as that will give you the best performance benefit. But, if you have regions on the page that must change dynamically per user, eg: you are saying 'Hi {username}' at the top of the page, then you need to look at Fragment caching.
Fragment caching is not as effective as page caching, since the output has to be stitched together from cached info and dynamic info, but it's usually still MUCH better than NO caching!
It's a bit of an art, to tweak the caching depending on what the page does and the load on the database, but it can make a page load many Orders of Magnitude faster than non-cached.
FYI - if the db queries are killing the site you may want to also look at taming them and/or caching their output individually, so that you don't have to keep hitting the database for the same information.
Also understand the 'varyByParam' for caching is pretty useful too - say you have a page in 3 languages, you can cache a page for each language by using the varyByParam, as long as your Url some sort of language component that the varyByParam can pick up.
HTH,
Lance

Building ASP.NET application - Best Practices

We are building an ASP.NET application and would like to follow the best practices. Some of the best practices are:
Server side Code:
Use catch blocks to trap & log low level errors too.
Use Cache objects to populate dropdowns etc. where we won’t expect the changes in the underlying data/database.
In case of error logging framework, provide emailing alerts along with logging the errors.
HTML code:
- Don’t write inline CSS.
- Place the JavaScript code (If needed by the page) at the end of the page unless the page needs it for load time actions.
Now coming to the point, Would you please share these best practice points if you have a comprehensive list of them already?
Some of the best practices that I've learned over time and written up for use at my company...many are mainly applicable to WebForms and not MVC.
Don't write .NET code directly in
your ASPX markup (unless it is for
databinding, i.e. Evals). If you
have a code behind, this puts code
for a page in more than one place and
makes the code less manageable. Put
all .NET code in your code-behind.
SessionPageStatePersister can be used in conjunction with ViewState
to make ViewState useful without
increasing page sizes. Overriding
the Page's PageStatePersister with a
new SessionPageStatePersister will
store all ViewState data in memory,
and will only store an encrypted key
on the client side.
Create a BasePage that your pages can inherit from in order to
reuse common code between pages.
Create a MasterPage for your pages
for visual inheritance. Pages with
vastly different visual styles should
use a different MasterPage.
Create an enum of page parameter key names on each WebForm
that are passed in via the URL, to
setup strongly-typed page parameters.
This prevents the need for hard-coded
page parameter key strings and their
probable mis-typing, as well as
allowing strongly-typed parameter
access from other pages.
Make use of the ASP.NET Cache in order to cache frequently used
information from your database.
Build (or reuse from another project)
a generic caching layer that will
wrap the ASP.NET Cache.
Wrap ViewState objects with Properties on your Pages to avoid
development mistakes in spelling,
etc. when referencing items from the
ViewState collection.
Avoid putting large objects and object graphs in ViewState, use it mainly for storing IDs or very simple DTO objects.
Wrap the ASP.NET Session with a SessionManager to avoid development
mistakes in spelling, etc. when
referencing items from Session.
Make extensive use of the applicationSettings key/value
configuration values in the
web.config - wrap the
Configuration.ApplicationSettings
with a class that can be used to
easily retrieve configuration
settings without having to remember
the keys from the web.config.
Avoid the easiness of setting display properties on your UI
controls, instead use CSS styles and
classes - this will make your styles
more manageable.
Create UserControls in your application in order to reuse common
UI functionality throughout your
pages. For example, if a drop down
list containing a collection of
categories will be used in many
places in the site - create a
CategoryPicker control that will data
bind itself when the page is loaded.
Use Properties on your UserControls to setup things like
default values, different displays
between pages, etc. Value type
properties can be defined on your
UserControls and then be set in your
ASP.NET markup by using class level
properties on UserControls.
Make use of the ASP.NET validation controls to perform simple
validations, or use the
CustomValidator to perform complex
validations.
Create an Error handling page that can be redirected to when an
unhandled exception occurs within
your website. The redirection can
occur via the Page_Error event in
your Page, the Application_Error
event in your Global.asax, or within
the section within the
web.config.
When working with pages that use a highly dynamic data driven
display, use the 3rd party (free)
DynamicControlsPlaceholder control to
simplify the code needed to save the
state of dynamically added controls
between postbacks.
Create a base page for all your asp.net pages. This page will derive from System.Web.UI.Page and you may put this in YourApp.Web.UI. Let all your asp.net pages dervice from YourApp.Web.UI.Page class. This can reduce lot of pain.
Use Application_OnError handler to gracefully handle any error or exception. You should log the critical exception and send the details of the exception along with date-time and IP of client to the admin email id. Yes ELMAH is sure way to go.
Use ASP.NET Themes. Many developers don't use it. Do use them - they are a great deal.
Use MembershipProvider and RoleProvider. And Never use inbuilt ProfileProvider - They store everything in plain strings. It will drastically slow-down the performance while performing R/W
Use Firebug for client-side debugging. Try to follow YSlow standards for web-applications. Use YSlow extension for FireBug.
Use jQuery for client-scripting.
Never store User Authentication information in session or don't use sessions to judge if user is logged on. Store only minimum necessary information in sessions.
Have a look at PostSharp. Can improve maintainability of your code and make you more productive.
Never ever Deploy asp.net application under debug configuration on production. Find out here what scottgu has to say about this.
User Web Deployment projects. It can transform web.config sections and replace with production server setings. It will merge all compiled code-behind classes into one single assembly which is a great deal.
Use Cookie-less domains to serve static resources like images, scripts, styles etc. Each client request is sent along with whole bunch of cookies, you don't need cookies while serving pictures or scripts. So host those resources on a cookie-less domain.
Minify scripts, stylesheets and HTML response from the server. Removing unnecessary line-breaks and white-spaces can improve the time-to-load and bandwidth optimization.
Forms:
Set Page.Form.DefaultFocus and Page.Form.DefaultButton to improve user experience
Check Page.IsValid in your Save button handler before proceeding.
General:
Understand and implement the techniques found in the article "TRULY Understanding ViewState"
Use Page.IsPostBack in your page events to stop code from running unnecessarily.
Use hyperlinks instead of posting and using Response.Redirect whenever possible.
a. Understand and use the second parameter of Response.Redirect (it "Indicates whether execution of the current page should terminate")
Use the Page Lifecycle properly.
Use the Per-Request cache (HttpContext.Items) instead of Cache where it makes sense.
Web.Config:
Deploy with <compilation debug="false">
Register your controls at the web.config level instead of the page level (i.e. #Register).
Themes:
When using Themes, put your static images in the Theme as well.
a. Don't link to the images directly from your markup, link to them from a skin file or css file in your Theme instead.
ex: <asp:Image SkinID="MyImage" runat="server" ImageUrl="Images/myImage.gif" />
I don't think try/catch blocks are always appropriate for low-level methods. You want to catch (and log/alert, even better!) any errors before they get to the user, of course. But it is often better for a low-level method to just lets its errors get raised up to a higher level. The problem I have seen with low-level error trapping is that it often lets a larger operation continue, but then a result that is not quite correct gets presented to the user or saved to the database, and in the long run it's much more difficult to fix. It's also just a lot of extra clutter in your code to put a try/catch at every level if you're not going to "do anything" with the error until it's raised up to a higher level.
Here are some similar questions that may help you.
.NET best practices?
Best way to learn .NET/OOP best practices?
This should probably be community wiki as well.
I would recommend a couple of books if you are interested in pursuing a journey to become a better, more productive developer. These books are language agnostic and as you can see by the user reviews, very very helpful.
Code Complete 2
Pragmatic Programmer
If you are looking for a .NET specific book, you may appreciate the following book:
Microsoft Application Architecture Guide [available online for free outside of print format]
ASP.NET
If you don't use Session state, don't
forget to turn off it.
Use Server.Transfer instead of Response.Redirect if possible.
Set expiration parameter in IIS.
Use GZip to compress the text files.
Use Server-Side and Client-Side validation together.
Use Url Rewriter or Routing to make friendly url for SEO.
Design
Write each class and its properties
of your CSS file in the same line. (To decrease the file size)
Use CSS Sprites. (To decrease request)

Resources