Question

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 = new FileInfo(context.Request.MapPath(context.Request.CurrentExecutionFilePath));
        //var file = fi.Where(x => string.Equals(x.Name, string.Concat(pageName, ".aspx"), StringComparison.InvariantCultureIgnoreCase)).SingleOrDefault();
        if (fi.Exists == false)
        {
           // think I had this the wrong way around, the url should come first with the renderer page second
            return PageParser.GetCompiledPageInstance(url, context.Server.MapPath("~/CMSPage.aspx"), context);
        }
        else
        {
            return PageParser.GetCompiledPageInstance(context.Request.CurrentExecutionFilePath, fi.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;
        }
Was it helpful?

Solution

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>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top