Sunday, 15 July 2007

.Net Photo Gallery Control (PhotoHandler)

I had a quick Google for a .Net control or library for creating an online photo album easily - and therefore save me some time in writing my own. I then found a reference on ScottGu's blog about a PhotoHandler, which is a little project of Bertrand Le Roy. It is basically one C# code file that can be used as a control on a page or you can just browse to the file itself and it will display the folders and images in the current directory. The best thing about it is the simple setup and you can just ftp some image folders onto your server and the control will just display it all for you - no need to update any aspx/content pages. Download the source from the projects PhotoHandler CodePlex pages. You'll notice a samples directory - these pages use the handler as a control which is how I like to use it. Useful points on PhotoHandler usage: Get the required MetaDataExtractor library and pop it in your web apps bin directory. Also, make sure you get version V2.2.2d - otherwise you'll get a The type or namespace name 'Directory' does not exist in the namespace 'com.drew.metadata' (are you missing an assembly reference?) error. If you are using the control in a sub directory of your site then yo need to set the HandlerUrl property on the control or you'll get no images or thumbnails displayed. If you want to hide some folders from the album viewer you can make a mod to the control. On line 1648 where the code checks for a few common .net directories:
if (dir.StartsWith("_vti_") || dir.StartsWith("app_") ||
    (dir == "bin") || (dir == "aspnet_client")) 
{
   continue;
}
Change this to :
if (IsHiddenFolder(dir)) 
{
    continue;
}
Add the two helper methods:
// Checks a string[] to see if the folder should be omitted
private bool IsHiddenFolder(string directoryName)
{
    if (directoryName.StartsWith("_vti_") || directoryName.StartsWith("app_") )
    {
        return true;
    }

    if (!isHiddenListLoaded)
    {
        LoadHiddenFolderList();
    }

    for (int i = 0; i < hiddenList.Length; i++)
    {
        if( hiddenList[i].ToLower() == directoryName)
        {
            return true;   
        }
    }

    return false;
}

// Loads a string[] from a text file
private void LoadHiddenFolderList()
{
    using (StreamReader reader = new StreamReader(Server.MapPath("HiddenList.txt")))
    {
        ArrayList lines = new ArrayList();

        while (reader.Peek() != -1)
        {
            lines.Add(reader.ReadLine().Trim());
        }

        hiddenList = lines.ToArray(typeof(string)) as string[];
    }

    isHiddenListLoaded = true;
}
Finally, put the text file with directories (one per line) to omit as HiddenList.txt in the same location as the control and add two static variables to the class required by the helper methods:
private static bool isHiddenListLoaded;
private static string[] hiddenList;
Goodluck :)

Monday, 9 July 2007

WML / WAP page won't display (WML debugging)

WML / WAP browsers tend to keel over and die if they encounter anything they don't like. If your WML / WAP browser isn't displaying your page then check the following: 1. Ensure the WML is well formed and valid, there is a W3 Schools WML validator you may find very handy. 2. WML / WAP browsers refuse to work if the content type you are returning in the HTTP 200 response isn't Content-Type: text/vnd.wap.wml, so ensure this is the case by logging or sniffing the communication (Ethereal is my weapon of choice). 3. The most strange behaviour I've seen is a WAP browser not displaying anything because the file extension of the file being displayed isn't .wml !!!

Friday, 6 July 2007

Detecting a Mobile / WAP Browser in code (using User-Agent)

I recently got a task to create a simple terms and conditions page that would be sent in a link via our SMS API as a SMS or WAP Push message. The idea being that the phone can browse to the URL via the WAP browser or alternatively use a browser on their PC or MAC. I wanted some sort of simple switch, to display a WAP WML page for a mobile browser or a full html page for a PC or MAC browser. I had a quick look at the HTTPRequest class and found a Request.Browser.IsMobileDevice bool flag. This would be perfect... if it worked! Having tested the flag with several makes and models of phone, it seemed to only work on a selection. After doing a bit of an investigation I found that all the mobile browsers I tested with had similar user-agent values ( Request.Headers["User-Agent"] ). They all contained a value "MIDP", e.g. Nokia6230i/2.0 (03.25) Profile/MIDP-2.0 Configuration/CLDC-1.1. As you can see, we can also grab the device model and manufacturer from the user-agent also. MIDP, or Mobile Information Device Profile. MIDP, combined with the Connected Limited Device Configuration (CLDC), is the Java runtime environment for today's mobile information devices (MIDs) such as phones and entry level PDAs. I found a useful MIDP device list at Club Java. Searching for midp in the user-agent should work pretty well as far as my tests show. And you can also check for additional values supplied in the HTTP request to ensure the redirection works when required. .Net code sample:
bool isWMLBrowser = false;
if (Request.Headers["User-Agent"] != null)
{
   isWMLBrowser 
         = Request.Headers["User-Agent"].ToLower().Contains("midp");
}

if (!isWMLBrowser)
{
   // Redirect to HTML page
}
else
{
   // Redirect to WML WAP page
}
Any one else have any other bright ideas?

Monday, 2 July 2007

Web page content / Dummy web text (Lorem Ipsum)

Whilst working on implementing a new design for the Esendex site I wanted to see what the layout looked like with content in place. I also wanted to use text that didn't distract me or other colleagues working on the design (i.e. not repeat 'hello world' 100 times), so I needed to make it look like readable English but not be :) I wondered if there was some sort of latin text generator similar to the dummy text used in the printing and type-setting industry? Google took me straight to a great site called www.lipsum.com, which is apparently the first correct content generator of this type on the web. Very handy :)