Update .NET website without reloading

Look into "Application Initialization" IIS 7.5, Windows 2008 R2 (harder to setup) IIS 8, Windows 2012

App Initialization allow any application (application pool not site) restart to overlap and use the old, still running the previous application while warming up the new application start. Once the new application is spun up (determined by URLs you can set), it will begin using the new application and shutdown the previous one. Using App Initialization in conjunction with methods to ensure session remains across application pool restarts can allow your site to reboot seamlessly. (Zhaph has a good note about the machine key.)

In addition to the above links for App Initialization configuration, you're going to want to look at what triggers a site restart - since the site restart doesn't use the Application Initiliazation the site restart will be not be seamless.

You can configure IIS so that a DLL update doesn't immediately trigger a site restart, nor changes to web.config (high ChangeNotification values on the httpRuntime and external config files, as relevant to your site).

The final result is that you can update the DLLs/code without a site restart, then force an app restart that will use the AppInitialization background warm up for the seamless change of code.

Doing these things in concert works quite well for seamless restarts.

There are a number of ways to handle what you're asking for, and a few different aspects to your question:

Handle small updates for promotions

What you're really after here is a content management system or similar that allows you to edit the content on the fly (think Wordpress/Drupal or from a .NET point of view N2 CMS, Umbraco, Orchard, etc.), however there are some things you could try if you haven't gone down that route.

Because ASP.NET only really reloads if you touch certain types of file (web.config(s), the contents of the /bin/ and /app_code/ folders mostly) - and has a configurable limit for "other file changes" (basically once you've modified so many files within your site the application pool will restart - NumRecompilesBeforeAppRestart) you could look at doing something where you check a different folder for some static (i.e. .html) files that you pull in and display as needed, or utilise the LoadControl method that takes a string path to an .ascx user control and dynamically loads it - how you determine which to show is a different question more suited to StackOverflow - however I'd recommend a naming convention based solution.

You could also look into using something like the Managed Extensibility Framework (MEF - which has been a full part of the .NET framework since version 4) which allows you to write a plugin based architecture and specify a folder outside of your /bin/ directory to monitor for new .DLLs - although I've not tried this to see if it will avoid the app restart issue, I have used this to good effect in a web environment for adding common functionality to a site.

If that doesn't appeal, the only other option I can think of would be to add the controls as "code-in-front" as we did in classic ASP - i.e. with a <script runat="server"> block instead of a compiled "code-behind" class that contains the logic to run the control - this will remove the need for a DLL change, at the expense of some first-time performance loss as the control is compiled on the fly - again you'll need to balance this with the NumRecompilesBeforeAppRestart if you're doing lots of little changes.

How do I persist sessions across app restarts?

This is possibly an easier issue to solve and involves three key steps:

  1. Configure the MachineKey (IIS7, but still holds for 8) to be a constant value rather than AutoGenerate - this means that when the AppPool recycles it will use the same key, and so will be able to decrypt session cookies, viewstate, etc. from before the recycle.
  2. Either setup a State Server or configure a Database to hold Session State.
  3. Switch from using InProc to StateServer or SQLServer in the SessionState element in your web.config.

This way you will have persistent sessions that survive an app restart. However, these aren't "free" - everything you store in session must now be serializable, and you will incur a slight performance hit as each page load will now require additional network trips to get, and potentially release the session data.

However, if you're in a position where it takes "several minutes" for the application to restart after a deployment, you may want to consider moving to a load-balanced environment, or at the least a hot-swappable Staging/Live setup (such as that provided by Azure/AWS/etc.) - this way you can take a server offline while you update it or get it ready with the new code and then swap it in - provided you've taken the steps to address shared sessions (see above) this will work fine with no impact to your users.