|
|
|
ASP.NET
-
This blog post was a long time coming and fortunately doesn't apply to IIS7, but I thought I would finally take a few minutes and cover this shortcoming with the ASPNET tab that ASP.NET 2.0 introduced into IIS 6 and IIS 5.
As I've covered in a previous post, only 1 version of ASP.NET can run at a time in each IIS Application Pool. When you want to target a newer or older version of the ASP.NET framework for a particular site or application, you must update that website or application.
When ASP.NET 1.1 was released
When ASP.NET 1.1 was released, the common way to do this was to use aspnet_regiis.exe from the command line. There was a serious shortcoming with that method though, as I detailed back in December of '03. (That article and attached script is long overdue for a revision which I'll cover later in this blog post.) The essence of what I said, and gave a sample script for, is that if you use aspnet_regiis.exe, it will cause an AppDomain recycle on ALL AppDomains on the server, even if you target a single site. This means that on a production server, it is not safe to use aspnet_regiis outside of a scheduled maintenance window unless you don't mind the impact of an AppDomain recycle. (for more information on what an AppDomain recycle is and what the impact is, check out this blog post) The alternate is to change all of the script mappings manually, which properly changes the framework version but has zero impact on other sites on the same server.
When ASP.NET 2.0 was released
When ASP.NET 2.0 was released, Microsoft provided a new tab in IIS called "ASP.NET" as seen in the following screenshot:

At first this appears to be a welcome addition, and for development computers, it really is. The issue is this:
The ASP.NET tab in IIS 5 and IIS 6 uses the aspnet_regiis.exe command in the background and, if used, will cause a full AppDomain recycle on the *entire server*.
It's not what most people would expect, and there is no warning provided, so be very careful about this. In fact, you may survive an AppDomain recycle without having anyone complain. Therefore, I'm sure oodles of people use this tab on production servers without realizing that they are blowing away InProc session state, causing slow first loads on the pages, and, for sites that take a long time to start up after an AppDomain recycle, possibly causing downtime.
At ORCS Web, when v2.0 came out, I cleaned up the script to handle more than 2 versions of the framework and to I made some other enhancements, but I never got around to blogging about it because there were some features that I wanted to add. The two features that it's lacking the most are 1) you have to manually enter the site ID rather than getting to pick from a list, and 2) it doesn't support changing the framework version for subfolders. I kept telling myself I would spend 1/2 a day and finish this, but never got around to it. So, I'll include it here, and if it interests anyone, feel free to use it. We've been running it in production for years and it works just great, but it could stand for some further improvements. You can download it here: Change_Framework_version.zip. (Note: at ORCS Web we use our own control panel to change the framework version now instead of this script, but it was based on this script)
When ASP.NET 3.0 and 3.5 was released
ASP.NET 3.0 and 3.5 followed a new trend. They aren't full side-by-side versions of the framework like v1.1 and v2.0 were. Instead they are add-on extensions to ASP.NET 2.0. So, when you set your site to use v2.0 of the framework but have ASP.NET 3.5 installed on the server, you are actually able to use all of the v2.0 - v3.5 features.
IIS 7
IIS 7 allows you to set the framework version at the application pool rather than the website. This change does not cause the server-wide impact and it is safe to do on a production server as long as you realize that the one app pool will have an AppDomain recycle.
In summary, the ASP.NET tab should not be run on a production server except during a maintenance window. The impact is pretty minor or non-existent for some sites, but it can be pretty bad for other sites. Just be aware that changing the framework version from the ASP.NET causes an AppDomain recycle on the entire server. The alternative is to manually change the script mappings which can be done using the script provided above, or manually item by item at the site or application level in IIS.
|
-
This quick post is for my own sake so I can find it again later. :-) I refer to the following link often.
Mike Volodarsky has put together a detailed list of breaking changes in IIS 7.0 and ASP.NET. For the most part IIS 7 has great compatibility with IIS 6 apps. The httpModules and httpHandlers section are two important web.config sections that need to be migrated from system.web to system.webServer in Integrated mode, but most other things will work without changes.
There are exceptions though, which his blog post details well: http://mvolo.com/blogs/serverside/archive/2007/12/08/IIS-7.0-Breaking-Changes-ASP.NET-2.0-applications-Integrated-mode.aspx
|
-
I thought I would spend a few minutes today testing out Graffiti from Telligent. Graffiti is a fairly new blogging and content management system (CMS) which is meant to be very easy to install and setup. True to its word, it is impressively easy to get up and going. There are a few things that I found that are worth noting.
I wanted to install this in a VDir on a shared server here at ORCS Web and use ISAPI Rewrite to make it appear to run in the root folder with its own domain name.
In brief terms the install involved the following:
-
Download Graffiti (it's less than 3MB for the limited non-commercial version that I downloaded.)
-
Extract and save to disk
-
FTP the web folder to the vdir on the server
-
Mark the vdir as an application (assuming IIS is installed and setup)
-
Ensure that ASP.NET 2.0 is installed
-
Ensure that the App_Data folder is gave write permissions for the application pool identity (assuming you use VistaDB which is what is used by default)
-
Test. It should work
-
Update the default passwords per the Graffiti installation instructions.
This confirmed that it works in a vdir without any issue. Just make sure to mark it as an application.
I also tried using ISAPI Rewrite so that one IIS site can be used for multiple websites. ISAPI Rewrite is an ISAPI Filter for IIS that allows for URL rewriting. Using ISAPI Rewrite 2.0, the rule looks like this:
RewriteCond Host: (www\.)?testGraffitiSite\.com RewriteRule (?!/graffiti)(.*) /graffiti$2 [I] # testGraffitiSite\.com is the domain name # graffiti is the name of the vdir in IIS
Note that ISAPI Rewrite works at a different level than ASP.NET, so any time that ASP.NET does a redirect for any reason, it will append the full IIS path. That means that you may start out with www.testgraffitisite.com and end up on www.testgraffitisite.com/graffiti. It will still work, but it adds the extra part of the path to the URL. There isn't any way around that with ISAPI Rewrite, so just make sure that the vdir is a name that you don't mind people seeing. Obviouslly you can install Graffiti in the root of the site so that this isn't an issue, but I wanted to prove that it works well with ISAPI Rewrite.
I ran into one issue when helping someone else that installed Graffiti on a shared server. When trying to view the page, it took forever and finally timed out without displaying any real errors. That made it difficult to troubleshoot but I eventually determined that it was because of that shared server running in partial trust. I was able to set the site to run in full trust and everything worked perfectly. At some point I'll dig further to see what trust settings needs to be changed so that this will work in partial trust, but for now I know that the modified medium trust permission on that shared server wasn't enough to run Graffiti and the error message wasn't clear at all, it simply timed out.
All said and done, it really wasn't difficult at all to get up and going, even running in a vdir with ISAPI Rewrite.
Once installed, the usability of Graffiti is great. It's easy to figure out, clean and nice and flexible.
|
-
A question was asked on a forum that I frequent which I thought was worth writting a blog about.
Q: What is the difference between an application and an Appdomain? I understand from my research so far that an Appdomain is a container within which ASPX runs and that Apppool is a process that starts the w3wp.exe worker process within which ASP applications run.
A: That's a good question. Here are some key differences:
-
An application is an IIS term, but it's one that ASP.NET utilizes. Essentially it creates a sandbox, or a set of boundaries to separate different sites, or parts of sites, from the others.
-
An AppDomain is a .NET term. (In IIS7, AppDomains play a larger role within IIS, but for the most part it's an ASP.NET term)
-
An AppDomain contains InProc session state (the default session state mode). So if an AppDomain is killed/recycled, all of your session state information will be lost. (if you are using the default InProc session state)
- Applications can have multiple AppDomains in them although often times there is a one-to-one relationship between them.
-
In IIS6 and greater, there is the option of creating groups, or "pools" of applications that can be bundled together or separated; however the server administer decides. These are called Application Pools. Each app pool runs under its own w3wp.exe worker process.
-
In IIS, it's easy to see an application. A new website is a separate application and any subfolder can be marked as an application. When they are, the icon beside the folder turnes into a picture of some gears. By right-clicking on the folder, you have the option of marking a folder as an application or removing it as an application, if it already is one. Also, in IIS6, in the Application Pools section, you can see all of the applications and which app pool they live under.
-
ASP.NET, on the other hand, doesn't give much visibility into AppDomains, at least not from any visual tools. This is done behind the scenes. Programmatically you can create them, tear them down or see a list of all running AppDomains.
-
You can recycle an application from IIS. In IIS5, you can't do it directly unless you recycle the entire web server, but in IIS6 and greater, you can recycle the application pool that the application lives under. It will gracefully die off and a new application will start up to replace it. Or, to word it another way, another w3wp.exe worker process will be started and then the old one will die off after it completes any currently running page requests.
-
You can recycle an AppDomain in ASP.NET through the 'touch trick'. There are a few ways to do it, but the most straight forward is to edit your web.config file in notepad and add a space to an insignificant place. Then save the file. This will cause the AppDomain to recycle. This *does not* touch the IIS application though.
-
Recycling an AppDomain will come pretty close to starting ASP.NET fresh again for that particular ASP.NET application, so although it doesn't recycle the apppool, it can give ASP.NET a fresh start in many situations.
|
-
There are many times when it is worthwhile to create a custom machineKey for your web.config file. This is worthwhile on a webfarm but also worthwhile on a stand-alone server so that your machineKey remains the same after an iisreset or application pool recycle. I've put together a simple tool that will generate a valid random machine key. It will create a validationKey and decryptionKey which you can copy and paste into your web.config file. This is random so there is virtually no chance of anyone else having the same keys. I hope you enjoy! http://www.orcsweb.com/articles/aspnetmachinekey.aspx
|
-
When Wally McClure came to Charlotte to give a talk on Atlas to the Charlotte User Group, I had an interview with him which is now live on Show #66 of the ASP.NET Podcast Show. I didn't dive in too deep, but we discussed Webfarm hosting and some of the topics I covered in my TechEd 2006 talk in Boston, and some of the new upcoming features in IIS 7.0. Check it out: http://aspnetpodcast.com/CS11/blogs/asp.net_podcast/archive/2006/08/17/504.aspx
|
-
This has haunted me a few times in the past, so for my own sake I figured I would write a quick blog that I can reference in the future. Hopefully others find it valuable as well. I ran into an issue today where the forms authentication timeout didn't seem to be taking affect. This isn't the first time that I spent more time that I care to admit troubleshooting the issue. For some reason, no matter how hard I tried, I couldn't remember the exact details of the previous times, so I started fresh again today. I even tested the timeout at 1 minute, like so: <authentication mode="Forms"> <forms name=".ASPXAUTH" loginUrl="Login.aspx" protection="All" timeout="1" path="/" slidingExpiration="true"> </forms> </authentication> I could log in and wait for 5 minutes without touching the page, but when I refreshed the page, I was still logged in. At this point I realized that the timeout value wasn't working at all. When I left the page untouched for 35 minutes, I would be logged off. As a web host, we continually get the opportunity to troubleshoot other people's sites and code. Today's was the same situation. It wasn't code that I wrote, but rather that of one of our clients at ORCS Web. I checked the docs, confirmed again that the timeout property is minutes and not seconds. (I did know this well but when things don't work, even simple things need to be double checked), and I checked the syntax of the rest of the tag. I also changed other things in web.config to break the site to confirm that web.config was actually being used. I call this the 'break' test. I googled it and found a number of people with the same error, but after reading post after post I wasn't any closer to figuring it out except that the trend seemed to suggest that it wasn't the syntax of the tag that was at fault, but rather some other code related issue. Solution Sure enough, I finally decided to take a closer look at the code, which fortunately was available to me, and I found that the developer had overwritten the default authentication and instanced his own FormsAuthenticationTicket. This overrode the web.config settings rendering them useless. I uncovered the following: FormsAuthenticationTicket ticket = new FormsAuthenticationTicket ( 1, // version txtEmail.Text, // name DateTime.Now, // issueDate DateTime.Now.AddMinutes(30), // expiration false, // isPersistent roles, // userData FormsAuthentication.FormsCookiePath // cookiePath ); Conclusion The web.config settings work as advertised unless they are explicitly overwritten from code. The web.config settings aren't used unless the default authentication is used or the developer specifically uses it. This is a reminder to myself because now that I think about it I remember that previous issues like this always resulted in code changes. They weren't a result of the web.config settings. Note to myself: When troubleshooting forms auth timeout issues, blame code earlier in the troubleshooting, chances are good that the web.config settings were fine all along. Misc tips Here are a few tips that I discovered or was reminded of today:
|
-
Like any good technology, ASP.NET continues to evolve as new versions are released. But, like anything else, this brings with it a number of considerations. Microsoft has done a great job of allowing multiple versions of the framework to run side by side. Version v1.0, v1.1 and v2.0 can all run together at the same time on the same server. Each site, or even a vdir (Virtual Directory) within a site can have its own version of the framework installed. Simply install the framework version on your server and it will be available to you. The install itself is quite small, for example the v2.0 download is 22MB. The Microsoft homepage for the .NET Framework is: http://msdn.microsoft.com/netframework/downloads/updates/default.aspxThere are a couple gotchas to consider with running multiple versions of the framework side by side. First, let's dig into IIS a bit. Following is a snapshot of Windows Task Manager on an IIS5 (Windows 2000) server: Notice the 3 processes called aspnet_wp.exe. There is one per version of the framework. (v1.0, v1.1 and v2.0) If a process for a particular version of the framework doesn't exist, as soon as it's needed, a new process will be spun up. This allows multiple versions of the framework to live beside each other in IIS5. No effort, no pain . . . it just works. Now consider the following IIS6 (Windows Server 2003) screenshot: Notice that there aren't any aspnet_wp.exe processes anymore, but there are w3wp.exe processes instead. IIS6 was an impressive upgrade that brought with it some new concepts. One key new concept is Application Pools. A system administrator is able to create groups of sites and place each site in its own group. Whenever a site needs to run, a w3wp.exe process will start for its application pool if it hasn't already started. This brings with it a number of welcome security, performance and management advantages. You are now able to specify your own Identity User which can be unique per Application Pool. In IIS6, the aspnet_wp.exe process is done away with, and the work that it did is now done within each w3wp.exe process. This has the same advantages I mentioned previously, but it has one big gotcha! You cannot run more than one version of the framework in the same application pool in IIS6.While multiple versions of the framework can co-exist on the same server, they can't co-exist in the same process. If you attempt to run multiple versions of the framework at the same time in the same process, the 2nd version that tries to run will fail with the following error: Server Application Unavailable The web application you are attempting to access on this web server is currently unavailable. Please hit the "Refresh" button in your web browser to retry your request. Administrator Note: An error message detailing the cause of this specific request failure can be found in the application event log of the web server. Please review this log entry to discover what caused this error to occur.
You will also receive Event ID 1062 in Event Viewer that says: "It is not possible to run two different versions of ASP.NET in the same IIS process. Please use the IIS Administration Tool to reconfigure your server to run the application in a separate process." What to doFortunately, the solution is easy enough. Simply create a new application pool and move the site that you will be upgrading to that pool. You can even base it off of the existing one if you don't have the password memorized for the existing one. This is all done within IIS. Once you have placed the site or vdir in its own application pool, then you are ready to upgrade to the new framework version. I'll cover the different ways to move between different versions of the framework in another blog within the next few days, but the key thing to walk away with now is that multiple versions of the framework cannot co-exist in the same worker process at the same time. IIS5 didn't have any issue with this, but IIS6 requires that each version be in its own app pool.
|
|