BlogEngine.NET and migration to IIS 7
This blog (and the its parent/main site) is now running on IIS 7 Integrated Mode and would like to share a little of my experience.
There were two major issues with I migrated these blog to IIS 7 [more]
1) Server Error in / Application - Request is not available in this context when I accessed the sites
*Of course I had customErrors ON so I had to turn it OFF before I was able to see this detail
Interesting, since the site obviously worked fine in IIS 6 and no changes were made. But after a few google clicks I ran into this written specifically for the error. IIS7 Integrated mode: Request is not available in this context exception in Application_Start from Mike Volodarsky. Implemented the suggestion and that did it.
Because of IIS 7 architectural changes the request context is not available in the Application Start. And since BlogEngine.NET loads extensions in the Application_Start event and the extension makes extensive use of the request context in path related code (also determining protocol et al) the error occured.
Based on the article
"Basically, if you happen to be accessing the request context in Application_Start, you have two choices:
1. Change your application code to not use the request context (recommended).
2. Move the application to Classic mode (NOT recommended)."
I chose option one otherwise I would have stayed with IIS 6. So what I did is follow his recommended solution and move the Extension loading part of BlogEngine.NET to the BeginRequest but made provisions so that it is only loaded on the first request (and once).
Copying from the article:
void Application_BeginRequest(Object source, EventArgs e)
{
HttpApplication app = (HttpApplication)source;
HttpContext context = app.Context;
// Attempt to peform first request initialization
FirstRequestInitialization.Initialize(context);
}
class FirstRequestInitialization
{
private static bool s_InitializedAlready = false;
private static Object s_lock = new Object();
// Initialize only on the first request
public static void Initialize(HttpContext context)
{
if (s_InitializedAlready)
{
return;
}
lock (s_lock)
{
if (s_InitializedAlready)
{
return;
}
// *** Perform first-request initialization here ... ***
s_InitializedAlready = true;
}
}
}
And that's it for the FIRST issue.
2) Site worked, but hmmm.. the styles are not being applied. Looking at the code, BlogEngine.NET uses httpHandlers to link to the stylesheets. accessing the link directly in the browser didn't return anything (not found) while doing the same on the old hosting account (IIS 6) returned the style info succesfully. So there must be something wrong with the handlers and modules.
Luckily I found this IIS 7.0 Integrated Mode Configuration Changes from BE.NET forum
Go ahead and read the article, but the bottomline is : in the web.config move the module and handler configuration sections from the <system.web> to <system.webserver> and a few minor changes. Resulting in (assuming you didn't make changes in this section since you downloaded BlogEngine.NET)
<system.webServer>
<modules>
<add name="UrlRewrite" type="BlogEngine.Core.Web.HttpModules.UrlRewrite" preCondition="managedHandler" />
<add name="ReferrerModule"
type="BlogEngine.Core.Web.HttpModules.ReferrerModule"
preCondition="managedHandler" />
<add name="CompressionModule"
type="BlogEngine.Core.Web.HttpModules.CompressionModule"
preCondition="managedHandler" />
<add
name="WwwSubDomainModule"
type="BlogEngine.Core.Web.HttpModules.WwwSubDomainModule"
preCondition="managedHandler" />
<!--The CleanPageModule below removes whitespace which makes
the page load faster in IE. Enable at own risk -->
<!--<add name="CleanPageModule"
type="BlogEngine.Core.Web.HttpModules.CleanPageModule,
BlogEngine.Core"/>-->
<!--Remove the default ASP.NET modules we don't need-->
<remove name="Profile" />
<remove name="AnonymousIdentification" />
</modules>
<handlers>
<add name="FileHandler" verb="*" path="file.axd"
type="BlogEngine.Core.Web.HttpHandlers.FileHandler, BlogEngine.Core"
/>
<add name="ImageHandler" verb="*" path="image.axd"
type="BlogEngine.Core.Web.HttpHandlers.ImageHandler,
BlogEngine.Core"/>
<add name="SyndicationHandler" verb="*"
path="syndication.axd"
type="BlogEngine.Core.Web.HttpHandlers.SyndicationHandler,
BlogEngine.Core"/>
<add name="SiteMap" verb="*" path="sitemap.axd"
type="BlogEngine.Core.Web.HttpHandlers.SiteMap, BlogEngine.Core" />
<add name="TrackbackHandler" verb="*" path="trackback.axd"
type="BlogEngine.Core.Web.HttpHandlers.TrackbackHandler,
BlogEngine.Core" />
<add name="PingbackHandler" verb="*"
path="pingback.axd"
type="BlogEngine.Core.Web.HttpHandlers.PingbackHandler,
BlogEngine.Core" />
<add name="OpenSearchHandler" verb="*"
path="opensearch.axd"
type="BlogEngine.Core.Web.HttpHandlers.OpenSearchHandler,
BlogEngine.Core" />
<add name="MetaWeblogHandler" verb="*"
path="metaweblog.axd"
type="BlogEngine.Core.API.MetaWeblog.MetaWeblogHandler,
BlogEngine.Core" />
<add name="RsdHandler" verb="*"
path="rsd.axd" type="BlogEngine.Core.Web.HttpHandlers.RsdHandler,
BlogEngine.Core" />
<add name="CssHandler" verb="*"
path="css.axd" type="BlogEngine.Core.Web.HttpHandlers.CssHandler,
BlogEngine.Core" />
<add name="JavaScriptHandler" verb="*"
path="js.axd" type="BlogEngine.Core.Web.HttpHandlers.JavaScriptHandler,
BlogEngine.Core" />
<add name="RatingHandler" verb="*"
path="rating.axd" type="BlogEngine.Core.Web.HttpHandlers.RatingHandler,
BlogEngine.Core" />
<add name="OpmlHandler" verb="*"
path="opml.axd" type="BlogEngine.Core.Web.HttpHandlers.OpmlHandler,
BlogEngine.Core" />
<add name="MonsterHandler" verb="*"
path="monster.axd"
type="BlogEngine.Core.Web.HttpHandlers.MonsterHandler, BlogEngine.Core"
/>
<add name="BlogMLExportHandler" verb="*" path="blogml.axd"
type="BlogEngine.Core.Web.HttpHandlers.BlogMLExportHandler,
BlogEngine.Core" />
</handlers>
</system.webServer>
And that did it for me :)
FROM : .NET Developer Notes on BlogEngine.NET and IIS 7 Migration