Prevent sharing DLL in IIS/ASP.net - asp.net

lets say I have two ASP MVC applications.
ProjectXXX
ProjectYYY - this is fork of ProjectXXX.
Both projects have same structure (project/assembly name), but it differs on some functionality (it will be deployed for other countries).
For testing purposes we deploy both applications on one server.
ProjectXXX - has own IIS pool
ProjectYYY - has own IIS pool
Problem
When I removed some functionality from assembly of ProjectXXX and run ProjectYYY it throws TypeLoadException : Could not load type 'Project.Namespace.IMyInterface' from assembly 'Project.Namespace'
It looks like ProjectYYY uses DLL from ProjectXXX (IIS (asp.net?) loads dll once, because it "thinks" assemblies are the same?)
How to force IIS not to cache those assemblies and load the proper one for both apps?
EDIT / SOLUTION:
I have found, that my application uses MEF composition. As for now I have changed how it searches for assemblies and problem looks like gone :)

if you create separate IIS Site for each, it should do the trick, as for each site a separate w3wp process is run. Having said that, you can't share same ip and port for 2 sites so if you need that, you'll have to play around with redirecting, url rewriting on IIS.

Related

Could an ASP.NET web application assembly be replaced during its run

I have an ASP.NET web application (Visual Stuido project type) in which everything is compiled into a single assembly, it is deployed in IIS. My question is if I have a new version of the assembly, is OK to replace it in IIS without bringing down the IIS? Or for a safe consideration, should I firstly shutdown the web server and then replace the assembly and restart? I am looking for a better solution to reduce server down time?
Yes. but it will cause an immediate Application Pool Recycling.
Quoting MSDN Blog:
Altering the following files will also trigger an immediate restart of the application pool:
web.config
machine.config
global.asax
Anything in the bin directory or it's sub-directories
We've reinstalled applications numerous times usnig the Visual Studio installer and it has replaced the assemblies with no problems. The only thing we find is that the first time we open the web page it takes a little while to open - possibly as it reads in the new assembly. We haven't had to to do an IIS reset or anything like that.
In addition on our dev environments (and because I am lazy) I often simply overwrite the assembly on the web server and that exhibits the same behaviour as above.
Taking down IIS is not an option for us, as we have many websites running on the same server.
I can't guarantee this is the best way to do it or that it won't cause problems, but it works for us.

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?

Publishing a simple .NET web service yields IIS "It is an error to use a section registered as allowDefinition='MachineToApplication' ..."

This error has been reported elsewhere on stackoverflow, but none of the answers seem applicable to my situation.
I'm publishing a simple .NET web service (.asmx) and when I check the link in production, I'm met with the famous error:
"It is an error to use a section registered as
allowDefinition='MachineToApplication' beyond application level. This
error can be caused by a virtual directory not being configured as an
application in IIS."
I've gone through the basics already, namely these three most popular hints:
1/ The directory has been created as an "Application" by right-clicking in IIS, et cetera. It's running in its own Application pool.
2/ There is no subdirectory containing any superfluous web.config files. It's just the one web.config.
3/ I've made sure that the namespace matches up with the web service definition, all that basic stuff. At any rate, the project runs fine locally and also runs fine when deployed to a test server. This is leading me to think 'permissions issue' on the prod server, but I'm at a loss since the normal IIS sites run fine.
So I guess what I'm asking is: is there a fourth-most-popular cause of this error that I"m missing?
Oh, the Web Service Application is set to allow web service calls for all versions of .NET installed on IIS.
Also, I'd be happy to leave this legacy approach behind and ditch the .asmx for WCF; however this is the piece of code I'm tasked with rolling out at present.
Thanks!
You need to make sure that your have the proper .net framework version selected in you Application Pool. You can check this by going into IIS manager and going to the Application Pools node. Right click on the application pool that is attached to the website that contains your service and select "Basic Settings" (this choice should be in the left hand column of the window too). Then from the drop down select the proper version of the framework. You might need to create a new application pool specifically for the child application if they need to operate on different versions of the framework.
If the parent site is using .net 4.0 your webservice is probably inheriting that or vice versa (2.0).
So in short, try switching your application pool to a different framework version and see if that clears it up.

IIS 6 to 7 is making me scared of web.configs

Hi guys,
We have a mixed development environment of three servers running: Win Server 2003 & 2008, IIS 7 & IIS 6, ASP.NET 2.0 & ASP.NET 3.5. Previously, all three servers were Server 03/IIS6/ASP.NET 2.0, but with this new change, I am finding that pushing/moving any applications from server to server is always a terrifying experience because there are always a variety of problems with the web.config from server to server. I used to consider myself a confident ASP.NET developer but now I am frightened to come to work every day.
I have always used the web.configs that VS generates for me on the Win 2003/ ASP.NET 2.0 server. None of our web.configs are "leet", they are just normal, although we do use ScriptManager and UpdatePanel.
To get by, as a temporary fix, I'm having to remember that when projects are moved/tested/deployed, never to move or overwrite any web.configs and things get confusing very fast. I've tried "ducttaping" like suggested here my web.configs with the new IIS7 stuff but even that doesn't work all the time.
What can I do here, what's going on? Is there a standard web.config that will work on all of the servers and do the UpdatePanel and ScriptManager ?
[edited question]
Since IIS6 is the baseline install for your application, you should make sure to run the application in "Classic" mode under IIS7. This makes configuration the same as an IIS6 box. This is how we run our web applications for now until we have fully migrated to 100% IIS7 server environments and we have zero problems with deployment/runtime.
To do this you can either choose to run your app under the built in "Classic .NET AppPool" that comes with IIS7 or, assuming you create your own custom application pools, just make sure you set the "Managed Pipeline Mode" to "Classic" under the "Advanced Settings" dialog for the app pool.
You should seriously look at web deployment projects for visual studio 2008.
This is an official add-on for Visual Studio that gives you a new project type called web deployment project. Among the most useful features is the ability to do web.config search/replace as well as pre-compiled builds of your web sites or web application projects.
In your case, what you'd do is create a solution configuration in visual studio for all of your target web servers. Then you'd create a web deployment project for your web app. In the properties for the deployment project you tell it how you want to compile the project and what web.config replacements you want to use for each solution configuration.
The end result should be that you can open Visual Studio, pick a solution configuration, build the deployment project. The build will create a folder with everything you need for that environment including the correctly configured web.config files. Then you just copy the folder to your server and you are up-and-running.
Best of all, since the different config files are all stored in the projecct, it lets you manage your configuration in one place and check it all into source control.
Do note that there is no equivalent in Visual Studio 2010. Instead, VS 2010 has a whole new deployment mechanism called MSDeploy. With 2010 you don't need a seperate project for deployments, and MSDeploy goes a lot further allowing you to package your SQL databases and other stuff too.
You can use the Classic mode under IIS6 by changing the process. That is actually pretty simple and it should work.
Another approach would be to automating your deployment process and have it so that it deploys the correct web.config to the server when you need to update your application.
If you run your IIS 7 websites using the Classic .NET App Pool, then the config files will match what you would use for IIS 6. That's probably the easiest thing to do until you're ready to migrate everything to IIS 7.
Knowledge is a great way to get over fear. Figure out what's going on (you're currently grasping at straws) and the fear will go away.
It's my guess that you'll do better if you refactor the code that uses the config file. Sloppiness there can definitely explain your weirdness and inconsistencies. You can't control much with your config settings if the code isn't behaving properly.

IIS7 fails to load aspx pages

I've been trying to migrate a fairly large web application from IIS6 to IIS7 the past few days, but every time it seems like we're about done, IIS7 fails to load aspx pages.
The application is a .net 3.5 webapp that makes heavy use of reflection and web services. We use 2 main components (each with their own web site in IIS7 although they share an application pool): the web UI (aspx pages), and the webAPI (asmx pages).
The webAPI portion runs perfectly (as far as we can tell; there are a few things we can't test from the browser), and the web UI pages load static HTM pages just fine. The problem is that once we attempt to view an aspx page (any aspx page), the whole thing just comes to a halt; no error is logged in the event viewer until a few minutes later when we get an IIS 5010 warning (worker process ignoring ping).
We've attempted to migrate the app in two different ways:
Manually: we moved all the necessary files and set up the virtual directories then converted them to Web Sites. Result: the worker process took up 100% of a single core and spun forever (until terminated manually)
Automatically: Utilizing the MSDeploy application from www.iis.net we archived the entire IIS6 web server and unpacked it into a blank IIS7 install. We had to turn off Forms Auth to get rid of a 401.2 error, but after that the result here was that the webAPI component still works just fine, but instead of the web UI worker process taking up 100% of a single core, it grew to about a third of the required memory then hung out doing nothing.
Either way, what happened from the user's point of view was the same.
Unfortunately, we can't even attach a debugger to the worker process because it doesn't seem to be loading managed code.
Details:
.net framework: v3.5
CLR version: v2.0
IIS Authorization mode: Anonymous
OS arch: x64
App arch: x86
Happens with both classic and integrated pipelines
Notes:
New web projects seem to work just fine in IIS7 and, of course, xml web services are also fine
temporary DLLs are created and stored in the temporary ASP.net DLLs folder, even though the worker process never seems to contain managed code.
New pages added to the web UI project also show the same behavior (Didn't hurt to try)
Updates:
We've narrowed down the problem to a single assembly. It's a wrapper for a third party web control. I'm looking into replacing it, we'll see if it fixes the problem.
http://support.softartisans.com/kbview.aspx?ID=1318
Turns out it was an issue with the vendor control. Wish their solution actually worked though...
Try to re-register ASP.NET:
http://msdn.microsoft.com/en-us/library/k6h9cz8h(VS.80).aspx
The typical command line syntax would be to command line to the ASP.NET 2.0 version of your framework and type:
aspnet_regiis -i
Are you using the "Classic" Pipeline Mode for your Application Pool. The "Integrated" one is the default in IIS7 and it introduced changes in terms of configuration. (One example is HttpHandlers that need a different configuration in web.config).
The "Classic" one mimics the IIS6 application pool, and should work with the same configuration as for IIS6.
If you prefer to use the Integrated Pipeline, there are some tools that will automatically try to convert you configuration files.
Scott Hanselman covers some of these tools in his blog post.

Resources