Can you publish asp.net webforms project keeping it online? - asp.net

We've quite a big project at work which sometimes needs to be published during the day. However, the application will (of course) crash during publish and show errors. (because the /bin is being overwritten)
Is there a way to avoid this? Sometimes a publish takes up to 3-4 minutes.
I know I can use the app_offline.htm file to display a message instead of them seeing the actual errors.

There isn't a way to have 0 downtime on a deployment. But you have some options
Deploy a pre-compiled site
To speed up the time taken for a site to be active after deployment, you can use ASP.NET Web Site Pre-compilation. This process will package the site so that it will not need to be compiled on-the-fly after deployment.
Benefits
Faster site startup
Less assets to deploy
Can be packaged via the Web Deployment Tool
Drawbacks
Debugging can be harder as the names are scrambled; Debug mode can be turned on for it though
You cannot edit a pre-compiled site; you must do a full re-deployment
You should still use the app_offline.htm so avoid yellow-screen-of-death errors
Add another web server
The best option for these scenarios is to have 2 servers with a load balancer in front of them. Then this way you use the load balancer to redirect active traffic to one node while the new application is being deployed.
Benefits
Parallel deployments do not affect the existing site
Have double the capacity for future expansion
Load balancing allows the load to be spread evenly across servers.
Drawbacks
Session now needs to be stored out-of-process. Therefore, you must check you can switch to an out-of-process session storage to confirm you do not have any serialization problems. StateServer is a quick one to get started with locally.
More maintenance overhead for a deployment, as you need to include load balancing configuration as part of your deployment processes. Network Admins are normally familiar with this.

Related

IIS 8 publish ASP.NET core application - file in use

Is it possible to publish an ASP.NET (core) application to a running site on IIS 8 without having to stop and start the website manually?
Visual Studio 2015 keeps giving the error that a file is in use. I'm using publish to the file system, because my Web Deploy to a server in our network fails at the end with an error that it cannot authenticate on the server with port 443.
I don't mind IIS having to recycle the application pool, but when I constantly have to put the app down, publish (which takes about a minute) and restart it, it's not really good for the users.
Another option would be something like 2 websites running the same application, but only if this is automatable. Then it would put down 1 of the 2, update this, put it on, put down the second, update this and start it.
A third option is something like a hot update, where I could just update the application while it being on.
Can anyone point me in the right direction (perhaps some blog posts), because my Google searches didn't give me any good information?
If you copy a file called app_offline.htm to the application folder IIS will gracefully stop your application and start serving the contents of the app_offline.htm file. When application is stopped you can copy your files. After files are copied remove the app_offline.htm file and IIS will start your app. VS does that for you when you deploy to Azure but not when deploying to file system.
You mention "two websites running the same application". Do you mean two web servers hosting the same app?
If you already have multiple web servers (a.k.a. cluster of servers, or web farm), you can simply take some servers out of the cluster and update them. That is how we push out our updates. We use software from Citrix for managing the server farm. It also handles load balancing. This type of software allows one to monitor the servers, so you can determine when all the users have "moved" off the web servers (that were recently taken out of cluster). Then you can iisreset, deploy the new build, and move on to the next server (or set of servers, depending on your configuration). We have more than 20 virtual web servers. Typically we take down half of the servers, update them, and take the other half down as we put the first half back in the cluster/farm. This should allow for uninterrupted service. I understand you want to automate the process. I'll assume you're using Windows NLB (network load balancing). You could write a PowerShell script to automate taking down the servers. Here's a reference:
https://technet.microsoft.com/en-us/library/ee817138
I understand this may be viewed as a workaround. I'm not sure if recycling the app pool is always necessary with ASP.NET Core. I wasn't able to find a definitive answer. Most production applications should be on more than one web server anyway. Even if you don't have a lot of users, you should have multiple web servers for failover purposes.

Temporary file upload location in Asp.Net MVC web deploy

I use Visual Studio 2013's "Publish" and Web Deploy to publish my Asp.Net MVC 5 website. However when I update my website, it won't work during the upload. I'm looking for a way to minimize the downtime of the website during the update. The website is running in a VPS and I have full access to it. One solution that came to my mind is to configure the Web Deploy to first put the uploaded files to a temporary folder and once the upload is finished, it should then replace the new files. This would make the update a few seconds tops. I can do this manually but that's not an elegant way to update one's website.
PS: Maybe there are better ways to update the website but so far I like the web deploy. It's much faster than FTP for instance.
One of the most interesting things I've seen is to have two websites. Only one of them is running at a time. After finishing the upload, you disable the active one, and enable the one you uploaded too.
This works well if both are in the same Application Pool and even works with sessions if you want (how to: Configure SQL Server to Store ASP.NET Session State).
I've never done it this way, seems a little to complex for the minimal down time there actually is, but it's one way.
Here's the solution that we use on a high traffic website with 4 web servers.
1) Files are moved to the server into /site/version-xxx
2) IIS Web Application is re-pointed to the new version.
All this is automated and synchronized across the web servers. The end user doesn't notice any difference. (we don't rely on sessions to persist the user experience, if sessions is a must for you and you don't want to interrupt them, then you need to consider to store them on an external system that will not flush them when the websites are repointed).
This approach also allows us to rollback to any previous version.

Setting up DLLs so we can update production ASP.NET app w/o full publish or app restart

We have DLLs that contain hundreds of custom client processes that are kicked off from an ASP.NET application. Our clients run these processes while performing data entry, and typically there's only 1 process per client. On any given day, we might update 2 or 3 of these processes.
Currently these are all housed in a series of DLLs, which means that we are publishing our application a couple times per day. As a result, any logged-in clients get booted out of the system since the publish causes an app restart.
Is there a way that we can update these DLLs without requiring a full publish each time?
If your client processes have a common API then you could host, the DLLs separately in a WCF (or similar) service, and call the client processes remotely. So basically, consider moving to a service oriented architecture.
Check out the Managed Extensibility Framework (MEF) from Microsoft. It provides not only dependency management but also plug-in like library loading. Most likely it's exactly what you're looking for.
You can switch to SQL server or state server sessions in order to perserve session and logged users after app restart. Or store these dlls in APP_DATA and load it dinamically. Then of course you have to think of some refreshing system and refresh loaded dlls with newly uploaded ones.
There is no sensible way to avoid an application restart. Please note the emphasis on the word sensible.

IIS App Pool/Restart and ASP.NET

We are using IIS7 to host an asp.net web-based application.
In this environment administrators and developers can deploy code to the application on a regular basis.
The new code or app goes as a DLL to the ASP.NET bin folder. Upon deployment of the new DLL, IIS restarts the process, impacting (slowing down) all online users.
Is there a way to configure IIS to run the process in the background and once ready make the switch from old state into new without impacting the users?!
Thanks in advance for your feedback!
IIS already does this, that's what recycling is all about. IT's loading the DLL's while the old version of the application is still running. only after this is completed the recycling is complete.
However loading the DLL's is only part of getting web applications ready, there might also be initial loads like loading/caching the user db etc.
These actions are not part of the recycle process, they happen after all DLL's reloaded and the recycling is already completed.
A while back I ran into this issue with an application that had a huge startup time due to heavy db activity/caching during startup. So I was interested if there is some functionality that allows us to execute code before the recycle is marked as completed, so that the application is first considered recycled when everything is ready to run. Basically what I wanted is some kind of staging functionality.
I was in contact with the IIS team regarding this issue, sadly they told me that no such functionality exists, nor is it planned.
To solve this you could try do the following:
Use alternating deploys:
You setup 2 Websites with separate application pools. One of them is the LIVE website the other one is the STAGED website. If you want to deploy changed you simply deploy to the STAGED website. After everything is loaded/cached etc. you switch the URL settings of the web applications to reroute incoming requests from the LIVE to the STAGED one. So the LIVE one becomes the new STAGED and the other way around. The next deploy would then go to the new STAGED again and so on.
UPDATE
Apparently they have created a IIS Module that provides this functionality by now:
IIS Application Warm-Up Module for IIS 7.5
The IIS team has released the first beta test version of the
Application Warm-Up Module for IIS 7.5. This makes warming up your
applications even easier than previously described. Instead of writing
custom code, you specify the URLs of resources to execute before the
Web application accepts requests from the network. This warm-up occurs
during startup of the IIS service (if you configured the IIS
application pool as AlwaysRunning) and when an IIS worker process
recycles. During recycle, the old IIS worker process continues to
execute requests until the newly spawned worker process is fully
warmed up, so that applications experience no interruptions or other
issues due to unprimed caches. Note that this module works with any
version of ASP.NET, starting with version 2.0.
For more information, see Application Warm-Up on the IIS.net Web site.
For a walkthrough that illustrates how to use the warm-up feature, see
Getting Started with the IIS 7.5 Application Warm-Up Module on the
IIS.net Web site.
See:
http://www.asp.net/whitepapers/aspnet4
If you use ASP.NET 4 Auto Start feature:
You can still choose to auto-recycle the worker processes from time to
time. When you do that, though, the app will immediately restart and
your warm up code will execute (unlike today - where you have to wait
for the next request to-do that).
The main difference between Warm Up and Auto Start feature is that the Warm Up Module is part of the recycling process. Rather than blocking the application for requests, while running the init code.
Only thing you get by using the Auto Start feature is that you don't have to wait for a user to hit the page, which does not help your case.
See the Gu's blog post:
http://weblogs.asp.net/scottgu/archive/2009/09/15/auto-start-asp-net-applications-vs-2010-and-net-4-0-series.aspx
UPDATE 2:
Sadly the Warmup Module has been discontinued for IIS 7/7.5:
http://forums.iis.net/t/1176740.aspx
It will be part of IIS8 though (It's now called Application Initialization Module):
http://weblogs.asp.net/owscott/archive/2012/03/01/what-s-new-in-iis-8.aspx
UPDATE 3:
As pointed out in the comments the Warmup Module resurfaced for IIS 7.5 as Application Initialization Module for IIS 7.5 after IIS 8 was released:
http://www.iis.net/downloads/microsoft/application-initialization
The first part of ntziolis answer is a wee bit inaccurate. The worker process isn't being recycled or restarted, it just keeps running. If this were the case, then in shared pool environments you would have sites knocked out every time a new one was deployed.
When you deploy a new ASP.NET application it's the site's "Application Domain" within the worker process is torn down, not the pool process.
In addition pool recycling is a completely separate concept to deployment
At this point in time in the commercial life of ASP.NET, during a deployment, a site will be in an inconsistent state until all of the site is deployed. There is still no good story about this from Microsoft at this time for single site on a single server deployments.
This is why ASP.NET has the special App_Offline.htm page. It's there so you can enable that page, deploy and then turn it off.
The second part of ntziolis answer is nearly correct but you don't need two sites or two application pools. You just need two file system folders that switch between being the physical folders for the site...if you're on a single server and not behind a load balancer or ARR.
If your sites were on a web server behind a load-balancer or ARR then having two different sites would make sense, you could route requests from one site to the other and round-robin on each deploy.
Obviously if there is a large amount of user generated content (uploaded files and the like) then you'd map a virtual directory in your site to a common location for this data.
In larger scale deployments where your app is running across (for example) a load-balanced environment you can do more sophisticated deployments.
For related questions please see:
How Do I deploy an application to IIS while that web application is running
Publishing/uploading new DLL to IIS: website goes down whilst uploading
Is smooth deployment possible with componentized ASP.NET MVC apps?

How to Plugin Web Pages dynamically in ASP .NET (and update the plugin)?

For regular assemblies one can use MEF to load assemblies dynamically. If a live update is required of those assemblies, the recommendation is to use AppDomains to host the dynamic assemblies (potentially one can use Managed Add-in Framework (MAF)). When requiring an update, the appdomain is stopped, the assemblies are updated and the appdomain is reloaded.
What about assemblies that are loaded by ASP .NET that contain that code behind classes? How can I update them without forcing a restart of the main appdomain. Is it possible to host some of my pages in a dynamic appdomain? How would you do that? Can this appdomain share login token and authentication stuff so the user doesn't have to re-login?
Thanks
MEF doesn't support AppDomain isolation, so unfortunately, even during recomposition, those assemblies that had previously been loaded are still loaded in the main web application AppDomain. There are two things you'd need to battle in ASP.NET:
Any changes to physical files (e.g. .aspx, .cshtml, etc), or any changes to configuration files (.config), or any changes to the \bin directory will cause the application to be recycled. This is due to two things, file monitoring of pages/configs, and file monitoring of the \bin directory (which is because by default ASP.NET uses shadow copying of files - this is recommended).
To use MEF in another AppDomain would require a hideous amount of cross-domain communication, either through serialisation or MarshalByRef, which I just don't think would ever be a clean implementation. Not sure how you would trigger BuildProvider instances used to dynamically compile your pages in another AppDomain either.
I'm wondering if you're thinking about this too much. Since IIS6, HTTP.SYS has managed the routing of incoming requests to the appropriate website, this is handled at the kernel level. Even if the main application did restart (which there are a variety of reasons why it could), no requests will be dropped, it would simply queue waiting for a new worker process before passing the request on. Sure, from the user's point of view, they may notice some idle time waiting for the new application to restart, but realistically, how often are you going to be making these changes?
A lot of application design suffers from over-engineering. You may want to design for every scenario, but realistically it is easier to maintain a system which is simple but extensible. In my opinion, wanting to do what you have specified would be classed as over-engineering. Keep it simple.
Using the session "StateServer" will preserve your authentication between app pool recycles (caused by file updates).
For your actual question:
Create a folder outside of your website that your app pool has access to.
Put your new assemblies in there
Have a Task/Thread/Web Service that reads the folder and loads the assemblies into the current App Domain
Assembly.LoadFrom(string) http://msdn.microsoft.com/en-us/library/1009fa28.aspx
The newer version of the assembly should take precedence when an instance is created
I guess your question is saying this method doesn't work? What error are you getting...

Resources