Re-assigning default.aspx

Feb 2, 2009 at 3:28 PM
I've created a page which inherits from BlogBasePage and it includes some content that is pulled from BlogEngine data as well as unrelated stuff.  I want this to be the first page users see, so I rename BlogEngine's default.aspx file to somethingElse.aspx.  Viewing the site in the browser works as expected, and since there are links on default.aspx to point to somethingElse.aspx, I can get to the original default page.  However, links on that page still target default.aspx instead of somethingElse.aspx.  For example, the month list contains links that look like this "/2008/08/default.aspx" and I need it to go to the renamed page instead.  Is there a configuration setting somewhere that lets you redirect the default main page for "blogengine" itself?  
Coordinator
Feb 2, 2009 at 8:50 PM
It doesn't look like 'default.aspx' is a configurable option within BlogEngine.  One brute force option is to do a Search & Replace of default.aspx within the code (core and non-core).  Another option is to add your own HttpModule that would look for default.aspx requests and do 301/302 redirects to somethingElse.aspx (this httpmodule would probably go between BE's WwwSubDomainModule and UrlRewrite modules in the web.config file).  Or a 3rd option is to create an HttpModule where you add an event handler for the EndRequest event.  In your event handler, you can replace default.aspx with somethingElse.aspx.

Both options 2 and 3 don't require modifying BlogEngine since you'd just be adding your own HttpModule on top of what's already there.  Option 1 is probably the most ideal in that it would be cleanest to just not generate default.aspx links.  There may be other options ... these are three that just came to mind.

But I was curious what you still plan on using default.aspx for?  The month list, for example, "/2008/08/default.aspx" would normally show all the posts for 8/2008.  But if you want somethingElse.aspx page to display the 8/2008 posts, what else is there for default.aspx to do?  Just curious ...
Feb 3, 2009 at 11:49 AM
Is #3 hard to do?  Could you show me what it might look like?

To answer your question, somethingElse.aspx would be the blog home page, while default.aspx would be the main site page that may contain some content pulled from the blog (the titles of the last 3 posts), but would also contain unrelated content perhaps from an non-blogEngine datasource.  It may also contain Flash content.  The idea is that most of my website will be BlogEngine-based, but I want to have a few custom pages with my own code. I want my custom pages to use the BlogEngine theme directly. I know BlogEngine allows you to create "Pages", but I don't think you can put regular ASP.Net code in those pages.


Coordinator
Feb 3, 2009 at 7:06 PM
For the 3rd option, here's code that would roughly work.  It turns out it's not actually the EndRequest event where you modify the output, but instead the PostRequestHandlerExecute event.  I didn't test this much, but it worked decently without looking into it much.  The regular expression logic could be improved.  Oh, and to be able to modify the outgoing content, it's important you disable HTTP compression in the Advanced Settings section in the BE control panel.

The AdjustOutput httpmodule needs to be registered in the web.config file.  If you're on IE6, it's the <httpModules> section.  If you're on IE7, it's the <modules> section within <system.webServer>.

==== WEB.CONFIG ====

<httpModules>
   ... existing modules ...
   <add name="AdjustOutput" type="AdjustOutput"></add>
</httpModules>


==== New file in App_Code folder ====

using System;
using System.Collections.Generic;
using System.Web;
using System.IO;
using System.Text.RegularExpressions;

public class YourStream : MemoryStream
{
    private System.IO.Stream _outputStream;

    public YourStream(Stream outputStream)
    {
        _outputStream = outputStream;        
    }
    private string adjustHyperlink(Match m)
    {
        if (m.Groups.Count == 2)
        {
            if (m.Groups[1].Value.Contains("default.aspx"))
                return m.ToString().Replace("default.aspx", "somethingElse.aspx");
        }
        return m.ToString();
    }

    private static Regex _hyperLink = new Regex("<a\\s{1}href=\"(?<url>.*?)\"?>", RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled);
    public override void Write(byte[] buffer, int offset, int count)
    {
        System.IO.StreamWriter stream = new System.IO.StreamWriter(_outputStream);
        System.Text.UTF8Encoding utf8 = new System.Text.UTF8Encoding();
        System.Text.StringBuilder sb = new System.Text.StringBuilder(utf8.GetString(buffer));

        string content = _hyperLink.Replace(sb.ToString(), adjustHyperlink);
        stream.Write(content);
    }
}

public class AdjustOutput : IHttpModule
{
    public void Dispose()
    {
        // Nothing to dispose
    }

    public void Init(HttpApplication context)
    {
        context.PostRequestHandlerExecute +=
            new EventHandler(OnPostRequestHandlerExecute);
    }
    private void OnPostRequestHandlerExecute(object sender, EventArgs e)
    {
        HttpApplication application = (HttpApplication)sender;
        HttpContext context = application.Context;
        if (!context.Request.Url.ToString().Contains("/admin/") &&
            context.Response.ContentType.Equals("text/html", StringComparison.OrdinalIgnoreCase))
        {
            context.Response.Filter = new YourStream(context.Response.Filter);
        }                
    }
}
Feb 3, 2009 at 7:17 PM
Ben - This is good. Thanks!  I appreciate it!