Manually refresh output cache in IIS7 - asp.net

Problem description:
On our website we use standard asp cache with duration set to 5h.
It works fine, but sometimes the publisher add some special content that need to be showed impatiently on many different sub-pages (example some promoted article).
That's what I need to do it's easy to use page like this:
mydomain.com/admin/clear-all-website-output-cache.aspx.
I want to clear SERVER SIDE CACHE.
Thanks for help.
we use: IIS7, ASP.net 3.5

See this ServerFault question: Will an IIS reset force cached items to be resent?
This says that you need to use IISRESET (or reset IIS any other way) to do it.
I assume recycling the application pool of the application will have the same effect. It's a good practice to have one application pool per application, so, this should be less problematic than resetting IIS if there are other critical applications.
If your app pool is shared with other applications, create a new one, and change the app pool in the application properties to the new pool. Likely will have a similar effect.
BTW, I do not think stopping and starting the website (assuming likely the app has its own website) will have a similar effect, as it will not stop the process instance that holds the cache, which is represented by app pool. Not 100% sure though.

Use cache dependency on some file, the cache will expire when the file changed.

Related

ImageResizer restarts application pool

We're having a problem where the application pools restarts (and loses all sessions) when deleting a folder in a virtual directory. This is not ImageResizers fault, but ASP.NET. We cannot replicate the issue on a static web site.
I'm wondering if someone has resolved this issue? We're thinking about creating a separate web page just for ImageResizer and image content. Maybe there is a simpler way?
This solution did not work for us: http://www.aaronblake.co.uk/blog/2009/09/28/bug-fix-application-restarts-on-directory-delete-in-asp-net/
IIS and ASP.NET - both - have independent FileSystemWatchers. If you disable these, the problem should go away.
See http://imageresizing.net/docs/howto/avoid-network-limit for more information.
While the article above mentions the problem from the perspective of a latent network-based storage, the problem can appear in other ways - such as upon directory deletion.
I also suggest avoiding deleting folders on ASP.NET websites; it's a painful goal, and likely to fail due to read locks. Goodnes, folder deletion rarely works on windows — even when it's not part of a web site being actively served to clients.
It seems to be possible to use IIS application instead of Virtual directory, and use a different application pool for the image archive. I tried, and the problem was solved... this appool restarted instead, which didn't affect the web pool. Great success!
However, I don't think we will be doing this either. It seems as a IIS application needs it's own bin folder. I had to copy the image resizer DLLs here. I also had to write another global.asax for auto 404 images in Application_Start. It works... I just don't want the image directory to have a lot of code in it. It is synced from a third party.

Double App Domains in ASP.NET 4 application

I've got an ASP.NET application running on IIS 7 with multiple application domains, and I can't fathom why there are multiple app domains in a single process. I've grepped my code base, and I'm not explicitly creating a second application domain. Is it possible that a recycle has failed to time out?
These double domains will persist for sometime.
If a recycle occurs because of a web config or binary change, both app domains will go down, and two new ones will start up.
These servers are subject to several binary patches and IISResets per day - sometimes there are 2 domains, sometimes only 1.
Web gardening is disabled.
I discovered this because there is a timer in the application heart-beating to the database, and noticed one day the server had two heartbeats.
In windbg, !dumpdomain shows me the following result: (filtered to only show names of app domains):
Line 59: Name: None
Line 66: Name: None
Line 372: Name: DefaultDomain
Line 460: Name: /LM/W3SVC/1/ROOT/MyAppDomain-1-129882892717131250
Line 4437: Name: /LM/W3SVC/1/ROOT/MyAppDomain-4-129285605131450579
Even though you aren't creating an AppDomain, a library that you are using might be. What third-party components are you using? Do you have any Inversion of Control or Dynamic Proxy libraries that might be responsible? Here's an explanation of this happening with Castle.
Are you sure the application is only running in one place in IIS? It's possible to have multiple IIS sites/applications running off of the same files. This would be consistent with (1) getting your debug info from the db, rather than the app, and (2) the recycle due to editing web.config consistently resulting in duplicate domains. If one location is more commonly accessed than the other this could explain why there is sometimes only one AppDomain.
If you are leveraging ASP.NET's dynamic compilation and shadow copying feature, ASP.NET will at times have multiple AppDomains. Jim Schubert wrote an article called ASP.NET, AppDomains, and shadow-copying which explains this in more detail as well as makes several suggestions as to how to modify web.config to customize this. He also has a helpful answer over at Does my ASP.NET application stop executing if I overwrite the DLLs? Shadow copying can be disabled by setting <hostingEnvironment shadowCopyBinAssemblies="false" />.
Update
I got sucked into Jim Schubert's blog and ended up reading this unrelated post on Allowing Only A Single Instance of a .NET application. If all else fails, you could use this approach to ensure only one instance of the application is running.
May have a look at your ApplicationHost.config.
have a look at: maxProcesses it should be 1.
It seems your IIS starts multiple worker-processes.
As suggested by the following answer https://stackoverflow.com/a/3318367/2001769
in another thread, it seems the ASP.NET runtime keeps a pool of HttpApplication instances (irrespective of maxProcesses / Web Garden).
I don't know if is possible, or even desirable, to control this pool. The best practice could be to instantiate all application singletons in the Application_Start event that is supposed to run only once per application and not once per pooled HttpApplication instance.
If there are multiple IIS Applications targeting the same path. An AppDomain will be created per such IIS Application if the app is invoked.
For example:
http://myServer/App1
http://myServer/App2
If both target the same path they still count as two different applications and two AppDomains will be created.

Random 401 errors on an auto compiled asp.net site when updated pages are pushed

We have an asp.net web site that is deployed on several IIS servers. The site is compile-on-demand as opposed to a pre-compiled web application.
Normally deployments go fine but every now and again we get a 401 for one of the deployed pages on one of the servers. There is nothing special about which page or which server apart from the fact that it's generally the higher traffic pages that it happens to.
The only way to rectify this is to deploy the same page again.
The ACLs look fine on the files themselves so the thought is that there is a file locking issue in the Temporary ASP.NET Files folder when the specific page is re-compiled.
Has anyone seen this before or have any suggestions how to avoid this?
Note: This only seems to have happened since we moved to .net 4.0
As far as I can tell we are getting a 401.3 Denied by resource ACL http://support.microsoft.com/kb/907273
But I have not been able to confirm this.
Those kinds of locks have always been a problem with live site deployment. The reason it's hard to replicate is because you are mid-request when copying/compiling on the server, and this ends up confusing IIS.
We operate a Blue/Green deployment strategy on a 4 tier architecture which has a web site over 4 servers at the top tier. Due to the complexity the architecture introduced for deployments, we needed a way to deploy without disturbing any traffic to the "live" site. Following Fowler's advice, but not quite in the same way, we came up with a solution that means we have 2 sites on each server (a blue and a green, or in our case site A and site B). The live site has the appropriate host header, and once we have deployed and tested to the non-live site, we then flip the headers of the 2 sites so that what was once live is now the non-live site, and vice-versa. The effect is, a robust deployment that can be done in hours and with the highest level of confidence.
This of course complicates your configuration and deployment slightly, but it's worth the effort. I guess it kind of goes without saying that you want to script both the deployment, and the host header swapping.
When i deploy to a server i bring the site down for a minute (or however long the deployment takes) - it may be down anyway during this time as pages are recompiled so it is not too much of a hit. You can do this by creating a file in the root of the app called app_offline.aspx (it needs at least 512 characters in length) once that file is created you can then copy the resources ot the folder knowing there will not be any locking issues. then when the copy is complete remove the app_offline file.
For those that want to achieve a .net website deployment without these issues, one option is to copy the new website files into a new folder first ( not the active website). Then you just change IIS to point to the new folder after all copying is complete.
This can be done in a single server environment for those of us on more limited resources without multiple servers per website.
At my work we write power shell scripts to deploy websites. The powers shell script creates a new directory with a time stamp, copies the new deployment there, then tells IIS to point the website to the new directory (leaving the old directories "orphaned" but still there).
If we really messed something up, we can simply revert by pointing IIS back at the previous date stamp directory. Otherwise if everything tests ok, we can delete the old folder.
This technique works well because you are never writing over a file while it is in use. However it still results in zero downtime. The only effect you will see is the normal .net "warm up" that occurs anytime you change the code behinds or assemblies.
I had several answers suggesting a new environment to deploy. This is something we have been considering for the long term but it's hard to justify the extra work when we regularly deploy only one or two files without a problem. I was really more interested in finding out what is actually happening and why.
In terms of a workaround, and this might sound obvious after the fact, a simple app_pool recycle solves the permissions issue and is much easier than testing for the issue and redeploying the file until the problem goes away.

Current working directory in ASP.NET code-behinds - can we depend on it?

Can we depend on the current working directory in ASP.NET code-behinds? Or, in other words, can we use relative paths, and be sure that they'll work?
If, in one page on a website, I set the current working directory to something specific, will it still be the same the next time another page on the website is loaded? When the same page on the website is loaded?
If I set the current working directory to something specific, in Page_Load(), can I be sure that it will still be the same by the time Page_PreRender() is called? Or could another page on the same website change it on me, in between? Could a page on a different website in the same application pool change it on me? A page in a different website in a different app pool?
In other words, what is the scope of the current working directory, in IIS? Is it specific to a page? Is it specific to a web site? Or is it shared among all pages in an app pool?
Where, among page, website, app pool, and server, are the boundaries that isolate different values of current working directory?
AppDomain.CurrentDomain.RelativeSearchPath will give you the physical path to the bin folder
Environment.CurrentDirectory is a simple wrapper around the GetCurrentDirectory and SetCurrentDirectory winapi functions. Indeed, trying to set the directory requires UnmanagedCode permissions. Whenever a function prevents your site from running in partial trust, you are right to be wary of depending on it. :)
From the SetCurrentDirectory documentation:
Changes the current directory for the current process.
The best explanation I can find that covers the relationship between the w3wp.exe process and an ASP.NET site is this answer. Any other page within your site could potentially change your page's current working directory. Any pages on any other site under the same application pool could potentially change your page's current working directory. These outside changes to the current working directory could happen at any time during your page's execution. On the other hand, a page on a site under a different application pool will not change your page's current working directory. The reason I say "could potentially" is that it gets even more complicated if you consider web garden scenarios, where there can be more than one process for a single ASP.NET site.
Now consider that SetCurrentDirectory is not thread safe:
Multithreaded applications and shared
library code should not use the
SetCurrentDirectory function and
should avoid using relative path
names. The current directory state
written by the SetCurrentDirectory
function is stored as a global
variable in each process, therefore
multithreaded applications cannot
reliably use this value without
possible data corruption from other
threads that may also be reading or
setting this value. This limitation
also applies to the
GetCurrentDirectory and
GetFullPathName functions. The
exception being when the application
is guaranteed to be running in a
single thread, for example parsing
file names from the command line
argument string in the main thread
prior to creating any additional
threads. Using relative path names in
multithreaded applications or shared
library code can yield unpredictable
results and is not supported.
Chances are that you don't want to depend on the current working directory. Having said that, given how foolish it is to rely on the current working directory, you can be reasonably certain that no other code will be touching it. :) A quick peek with Reflector shows that no .NET framework code changes it. A few functions do check it though, so watch out for those. If you control the deployment environment, you can ensure that your site runs in its own application pool. With proper synchronization technique, you should then be able to safely update the current working directory. I wouldn't consider it anything other than a hack though.
Links should be created relative to the site root using the tilde (~) operator:
Some Page
Within a server, an application pool completely isolates your site so that if some other site crashes on the same server, it won't bring down your site with it. IIS is pretty much site-specific with the added isolation benefits of app pools. I can see no practical use in trying to change a link on one page from the code-behind in another (or maybe I don't quite understand the question).
Here's a summary of the IIS architecture:
http://learn.iis.net/page.aspx/243/aspnet-integration-with-iis-7/

How do I force ASP.Net to invalid (and thus reload) the current application instance?

Basically I want the effect that would occur if I were to edit the web.config file. The application basically completely unloads itself and starts again, thus re-firing Application_Start and also ditching any dynamically created Types created by the now-defunct AppDomain.
EDIT
I need to do this in my C# code inside my web application. I know it can be done; I did it ages ago but have since lost the code and forgotten how I did it.
For full trust you can use HttpRuntime.UnloadAppDomain(). If you aren't running in full trust you can modify the last write time on the web.config file. Rick Strahl has wrapped these two approaches up in a nice class.
You can "touch" the web.config file (i.e. rewrite it to disk unchanged), or any file in the bin directory to recycle the application. Of course this means the identity under which your application is running needs appropriate permissions.
Lately I seem to be answering my own questions a lot :P
Here we go:
HttpRuntime.UnloadAppDomain();
If all the options above fail, you can also create an endless recursive function as a final resort. The resulting stackoverflow exception will force a reload of the application. (don't do this when you have the visual studio debugger attached)
In IIS you can recycle the worker processes. You don't need to restart IIS.
http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/24e3c22e-79a9-4f07-a407-dbd0e7f35432.mspx?mfr=true
If you have created a separate application pool for your application, you can reset the Application Pool.
In general, it's always a good idea to have separate app pool's for each application.

Resources