views:

32

answers:

1

Hi,

I am in the middle of writing a CMS system and after reading and working through a few examples, I have settled on HttpHandlerFactory to perform what I need.

the key point is our sites are generally a mix of copy and registration processes. So I currently need to use the default HttpHandler for aspx to render the physical registration pages until I can work a way to content manage them too.

after creating the handler class I added the following to my website's web config

<add verb="*" path="*.aspx" type="Web.Helpers.HttpCMSHandlerFactory, Web.Helpers"/>

As the above path handles physical and cms driven pages, with a small check in the code I am able to see if the page physically exists and can then render the desired page.

    public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
    {
        string pageName = Path.GetFileNameWithoutExtension(context.Request.PhysicalPath);
        context.Items.Add("PageName", pageName);
        DirectoryInfo di = new DirectoryInfo(context.Request.MapPath(context.Request.ApplicationPath));
        FileInfo[] fi = di.GetFiles("*.aspx");
        var file = fi.Where(x => string.Equals(x.Name, string.Concat(pageName, ".aspx"), StringComparison.InvariantCultureIgnoreCase)).SingleOrDefault();
        if (file == null)
        {
            return PageParser.GetCompiledPageInstance(string.Concat(context.Request.ApplicationPath, "/Default.aspx"), url, context);
        }
        else
        {
            return PageParser.GetCompiledPageInstance(string.Concat(context.Request.ApplicationPath, "/", file.Name), file.FullName, context);
        }
    }

The question I have is should I be using something other than PageParser.GetCompiledPageInstance when there is a physical page?

Update: since the above I have gone on to develop and HttpHandler for images, which again works on the same principle of if the image exists use it else serve from database. Had a bit of problem with png files but the below process works for the file formats shown.

        byte[] image = null;
        if (File.Exists(context.Request.PhysicalPath))
        {
            FileStream fs = new FileStream(context.Request.PhysicalPath, FileMode.Open, FileAccess.Read);
            BinaryReader br = new BinaryReader(fs);

            image = br.ReadBytes((int)fs.Length);
        }
        else
        {
            IKernel kernel = new StandardKernel(new ServiceModule());
            var cmsImageService = kernel.Get<IContentManagementService>();
            var framework = FrameworkSetup.GetSetFrameworkSettings();
            image = cmsImageService.GetImage(Path.GetFileName(context.Request.PhysicalPath), framework.EventId);
        }

        var contextType = "image/jpg";
        var format = ImageFormat.Jpeg;

        switch (Path.GetExtension(context.Request.PhysicalPath).ToLower())
        {
            case ".gif":
                contextType = "image/gif";
                format = ImageFormat.Gif;
                goto default;
            case ".jpeg":
            case ".jpg":
                contextType = "image/jpeg";
                format = ImageFormat.Jpeg;
                goto default;
            case ".png":
                contextType = "image/png";
                format = ImageFormat.Png;
                goto default;
            default:
                context.Cache.Insert(context.Request.PhysicalPath, image);
                context.Response.ContentType = contextType;
                context.Response.BinaryWrite(image);
                context.Response.Flush();
                break;
        }
+1  A: 

I'm not sure if this completely answers your question... I've also built an ASP.NET CMS that was HttpHandler driven, and which also allows for physical .aspx pages. As I only had a small number of physical .aspx files and locations the easiest way to manage execution was via web.config.

Firstly, I configure the website (in general terms) to use my handler - except for the login page (as an example):

<add verb="*" path="login.aspx" type="System.Web.UI.PageHandlerFactory"/>
<add verb="*" path="Register.aspx" type="System.Web.UI.PageHandlerFactory"/>
<add verb="*" path="*.aspx" type="Morphfolia.PublishingSystem.HttpHandlers.DefaultHandler, Morphfolia.PublishingSystem"/>

The other thing you can do is isolate by location, so for this part of the site I'm opting to use the out-of-the-box ASP.NET handler which normally processes "classic" ASP.NET requests:

<location path="Morphfolia/_publishing">
  <system.web>
    <httpHandlers>
      <add verb="*" path="*.aspx" type="System.Web.UI.PageHandlerFactory"/>
    </httpHandlers>
  </system.web>
</location>
Adrian K
Your right, it wasnt a complete answer but has sort of validated what I am attempting.
Luke Duddridge