Executing an ASP.NET HttpModule for specific pages only

By default an ASP.NET HttpModule runs for all webpages on a website. If you use an HttpHandler instead then it is possible to specify the path it executes for in the web.config, but using a handler may not always be possible/desirable in your circumstances.

A module can read the web.config though, so you can create an appSetting entry containing the pages that you want to show, like this:

<appSettings>
    <add key="ModulePages" value="Wibble.aspx,Wobble.aspx"/>
</appSettings>

And then your module sourcecode can be adjusted similar to the following (the key code is in CheckPath()):

   public class HumMasterPage:IHttpModule
    {
        private HttpApplication _current = null;

        #region IHttpModule Members

        public void Init(HttpApplication context)
        {
            _current = context;
            _current.BeginRequest += new EventHandler(context_BeginRequest);
        }

        #endregion


        /// <summary>
        /// DynamicMasterPath appsetting tells us which path the module should run for
        /// </summary>
        /// <returns>true if the current path is in the allowed paths, or allowed paths are not specified (i.e. all are allowed)</returns>
        private bool CheckPath()
        {
            if (ConfigurationManager.AppSettings["ModulePages"] == null)
                return true;

            string[] allowedPaths = ConfigurationManager.AppSettings["ModulePages"].ToString().Split(',');
            
            foreach(string allowedPath in allowedPaths)
            {
                if (_current.Context.Request.Url.PathAndQuery.Contains(allowedPath))
                    return true;
            }

            return false;
        }

        void context_BeginRequest(object sender, EventArgs e)
        {
            if (CheckPath() == false)
                return;
 
            // Do your module stuff here...
        }

    }

You obviously may need to modify it if you have several pages named the same in your site, and I have to admit that I’ve only tested with Webforms, not MVC (I can’t remember off the top of my head if MVC routing is done before or after the module processing). It works well with Webforms however, and there are often better ways to process the stream using MVC anyway.

Advertisements

Custom stored procedures returning DataSet instead of TList in NetTiers – and how to change!

When we upgraded our Nettiers installation on an old website recently some of our custom stored procedures suddenly started to return a DataSet rather than a TList. This is understandable – the stored procs were complex and so Nettiers wouldn’t have been able to guarantee the return type. Probably the earlier version of Nettiers was wrong to trust us in the first place. However *we* knew that it would always return the correct thing, and there were far too many places in the code to go back and recode it all to cope with a Dataset.

It seemed tricky to find the answer so I’ve reposted it here from the original source (http://community.codesmithtools.com/nettiers/f/16/p/10097/37547.aspx):

Set the Codesmith template setting AllowCustomProcMultipleResults (under the CRUD -Advanced section) to True and then regenerate. This seems to tell Nettiers to just trust that you know what you are doing, and sets the return type to that of the entity in the provider.

FileUpload control with UpdatePanel (WebForms)

The asp:FileUpload control rather irritatingly does not work within an UpdatePanel in ASP.NET Webforms. This is probably something to do with security (which always seems to be an issue with AJAX!).

To get round this problem you can of course take it out of the UpdatePanel and have it on a separate form, but that is not really that slick, and I expect the main reason you are trying to do this is for slickness!

The solution is to put the upload control and associated upload functionality on another aspx page, and then include the page within your form using an iframe with the frameborder property set to zero. Of course that is not perfect, as you will need to provide a separate button for uploading, which might be irritating to the user. On the other hand that also allows you to display things like photo uploads relatively easily and apparently seamlessly.

Your main problem will be giving the upload page the information about where to store the file/photo (if it associated with a specific data record). When updating a record this can be passed as a parameter to the page request. Adding a record is more tricky. In this case if you generate your data’s key prior to saving then no problem, but if you allow the database to do it after saving it is a problem, as you can’t pass it through to the upload page! In this scenario the best process flow might be not allow file uploads in insert mode – just ask the user to save the data record, then have the page automatically go into edit mode afterwards for photos.

It all feels a little bit hacky but sometimes that is just the way AJAX works!