Hugoware

The product of a web developer with a little too much caffeine

Archive for November 2009

Vacation Week!

with 3 comments

I’ve been on vacation this week and didn’t spend much time programming… well, not on anything official at least. Mostly I’ve been poking around at stuff between games of Modern Warfare 2 and my chore list from The Wife. One of the more interesting things I’ve been playing with is using MySql with MonoDevelop and Ubuntu.

Since MSSQL normally costs extra in a hosted environment I typically end up using a handful of XML files or serialization to keep track of information. But now that I’ve been using Mono I started to consider that MySQL might be an option for further projects (especially since it’s normally free in hosted environments).

I did a post recently about getting started with cross platform development where I listed some resources to get you started but I didn’t mention anything about using SQL. Below are some tools that can get you started.

MySQL (Server)
Setup for the actual SQL server instance — Standard stuff here…

MySQL GUI Tools and the MySQL Workbench
Great set of tools to work with your SQL server instance. Just look at how polished some of these tools actually are!

A couple warnings before you get too far. Linux (or at least Ubuntu) is case sensitive — this means that if you try to include the DLL files for MySQL in your Mono project the case must match! When I downloaded the files they were all in lower case but the DLLs were imported using camel case (mysql.data.dll as opposed to MySql.Data.dll)

Also, I don’t see any way to use LINQtoSQL with MySQL (and it wouldn’t make sense if it did anyways). Be prepared to start writing your own queries just in case.

Written by hugoware

November 29, 2009 at 8:04 pm

jLinq Update (2.2.1)

with 10 comments

I’m off from work this week so the first thing I did was get some work done on jLinq. I’ve had a few bugs I’ve needed to sort out along with a new feature I wanted to implement. I’m also going to be working on documentation this week. Previously, I had created a Wiki and was hoping that people might add to the documentation… but instead spam bots pretty much ruined it so I’ll be starting over from scratch… oh well..

New Features

jLinq itself doesn’t really have a new feature but instead a new way to get the jLinq library. Instead of simply downloading a standard jLinq library you can use the new online jLinq Framework Generator to select only the functionality that you want to include. You can still download the basic pack but this option gives you a little more control what goes into your version of jLinq.

Changes

The most notable change for jLinq is that all of the operator commands have been included as standard functions for the framework. Before, these functions were actually methods extended onto the framework. Since these functions are required for jLinq to work I’ve moved them so that they are in every jLinq framework by default.

Bug Fixes

orderBy with joined records would return incorrect results
jLinq uses eval to figure out the values of field names since you can provide methods, array indexes or whatever. The code used to sort the values wasn’t getting the values correctly so the sorted result was always wrong.

using 0 in certain comparisons would return incorrect results
Ah, this one was fun. So check out the code below…

var values = [ 0 ];
var index = 0;
var a = !values[index];
var b = values[index] == null;

So what is a and what is b? If you said true and false then give yourself a cookie.

jLinq uses the number of arguments passed to help determine if anything is being memorized (like the field name). jLinq makes a quick pass to select all values until it finds a null value… or at least that is what I meant for it to do. Unfortunately, I wasn’t thinking when I wrote that method and didn’t check explicitly for null.

Feedback

If you find any problems with jLinq or have any suggestions, please leave a comment or contact me directly.

Written by hugoware

November 23, 2009 at 9:03 pm

Code Performance Measuring With Enclosures

with 2 comments

I’m sure that there are many libraries available to help measure the execution of time inside of an application but I spent some time the other day writing a quick class to help me time segments of code.

The idea was to use an Anonymous Method to wrap a section of code with a Stopwatch to check the total time of execution. Additionally, since methods could be Anonymous, you could nest the measurements to see how long specific sections would take.

Anyways, here is some source code to play around with.

/// <summary>
/// Simple measuring of sections of code
/// </summary>
public class CodeBlockTimer {

    #region Private Fields

    //holds the current time for this measurement
    private Stopwatch _OverallTime;

    //container for the measured code sections
    private List<object> _Blocks = new List<object>();

    //the nested level for the code block
    private int _Level = 0;

    #endregion

    #region Methods

    /// <summary>
    /// Stops this code block timer
    /// </summary>
    public void Stop() {
        this._OverallTime.Stop();
    }

    /// <summary>
    /// Adds a block of code to measure
    /// </summary>
    public void Measure(Action block) {
        this.Measure(block.Method.Name, block);
    }

    /// <summary>
    /// Adds a block of code to measure with a defined name
    /// </summary>
    public void Measure(string identity, Action block) {

        //start the overall timer if needed
        if (this._OverallTime == null) {
            this._OverallTime = Stopwatch.StartNew();
        }
        //check and make sure this timer wasn't already stopped
        else if (!this._OverallTime.IsRunning) {
            throw new InvalidOperationException(
                "This CodeBlockTimer has already been stopped and cannot measure additional code blocks."
                );
        }

        //create the container
        _StartBlock start = new _StartBlock(identity, this._Level++);
        _EndBlock end = new _EndBlock(start);

        //run this section of code
        this._Blocks.Add(start);
        start.Timer = Stopwatch.StartNew();
        block();
        start.Timer.Stop();
        this._Blocks.Add(end);

        //and revert the level
        this._Level--;

    }

    /// <summary>
    /// Writes the results to the Console
    /// </summary>
    public void ToConsole() {

        //make sure all of the jobs have finished
        if (this._Level > 0) {
            throw new InvalidOperationException(
                "Cannot report the final summary until all code blocks have completed."
                );
        }

        //stop the overall timer
        if (this._OverallTime.IsRunning) {
            this._OverallTime.Stop();
        }

        //showing code groups
        Func<int, string> treeLine = (count) => {
            string start = string.Empty;
            for (var i = 0; i < count; i++) {
                start = string.Concat(start, "|  ");
            }
            return start;
        };

        //display each code block
        foreach (object item in this._Blocks) {

            //if this is a starting block, show the work has started
            if (item is _StartBlock) {
                _StartBlock block = item as _StartBlock;
                Console.WriteLine(
                    "{0}[Begin] {1}: {2}",
                    treeLine(block.Level),
                    block.Identity,
                    block.Level
                    );
            }
            //if this is the closing block, display the timer result
            else if (item is _EndBlock) {
                _EndBlock block = item as _EndBlock;
                Console.WriteLine(
                    "{0}[End] {1}: {2} ({3})",
                    treeLine(block.StartingBlock.Level),
                    block.StartingBlock.Identity,
                    block.StartingBlock.Level,
                    block.StartingBlock.ToTimeString()
                    );
            }

        }

        //and display the summary
        Console.WriteLine(
            "\nTotal Blocks: {0}\nTotal Time: {1}", 
            this._Blocks.Where(item => item is _StartBlock).Count(),
            CodeBlockTimer._ToTimeString(this._OverallTime.ElapsedMilliseconds)
            );
    }

    #endregion

    #region Static Methods

    //creates a meaningful time string from some milliseconds
    private static string _ToTimeString(long ms) {
        if (ms > 60000) {
            return string.Format("{0:0.0}min", (double)ms / 60000d);
        }
        else if (ms > 1000) {
            return string.Format("{0:0.0}sec", (double)ms / 1000d);
        }
        else {
            return string.Format("{0}ms", ms);
        }
    }

    #endregion

    #region Timing Classes

    //the marker for the start of a code block
    private class _StartBlock {

        //starts a new block to check the starting time
        public _StartBlock(string identity, int level) {
            this.Identity = identity;
            this.Level = level;
        }

        //the identifying name for this code block
        public string Identity { get; private set; }

        //the level this starts at
        public int Level { get; private set; }

        //the timer for this code block
        public Stopwatch Timer { get; set; }
        
        //provides a meaningful time value
        public string ToTimeString() {
            return CodeBlockTimer._ToTimeString(this.Timer.ElapsedMilliseconds);
        }
    }

    //marker for the finishing of a code block
    private class _EndBlock {

        //starts a new block to check the ending time time
        public _EndBlock(_StartBlock start) {
            this.StartingBlock = start;
        }

        //the open block this code was started in
        public _StartBlock StartingBlock { get; private set; }
    }

    #endregion

}

You can use the code inline with existing code to measure sections of the code. If you are using an existing method then the name will automatically appear in the final report. Otherwise you can use the default name or provide your own identity (which can help provide meaningful names for Anonymous Methods).

//create a monitor
CodeBlockTimer monitor = new CodeBlockTimer();

//start measuring a block
monitor.Measure("First Method", () => {
    
    //simulate execution time
    Thread.Sleep(300);

    //measure a block without an identity
    monitor.Measure(() => {
        Thread.Sleep(500);

        //measure a defined method
        monitor.Measure(DoSomething);
    });

    //provide an identity for an anonymoure method
    monitor.Measure("Quick Call", () => {
        Thread.Sleep(250);
    });

    //more simulated execution time
    Thread.Sleep(300);

});

//stop measuring the timer (or simply call ToConsole())
monitor.Stop();

//Display the results of the method to the console
monitor.ToConsole();

And the results…


[Begin] First Method: 0
| [Begin] <Main>b__1: 1
| | [Begin] DoSomething: 2
| | [End] DoSomething: 2 (1000ms)
| [End] <Main>b__1: 1 (1.5sec)
| [Begin] Quick Call: 1
| [End] Quick Call: 1 (250ms)
[End] First Method: 0 (2.4sec)

Total Blocks: 4
Total Time: 2.4sec

Anyways, I’m sure there is a hundred other ways you could get better results — but this might be good enough for small quick measurements.

Written by hugoware

November 18, 2009 at 11:39 pm

More On Cross Platform Development

with 6 comments

Up until about 6 months ago I was a Windows only developer. I thought it would be cool to mess with other operating systems and languages but it just wasn’t worth the time. I’m one of those devs that is more interested in creating software than learning new ways to create new software. Don’t get me wrong, I’m always impressed with those people that knows 14 different languages on 3 different operating systems — but I just don’t aspire to be that guy.

However, Mono has really opened up opportunities for me that weren’t available before. If you don’t know what it is, the easiest way to describe it is .NET everywhere. Write something in .NET and use it on Windows, Mac or Linux.

Mono doesn’t just apply to desktop apps either. You can actually write WebForms or MVC apps as well. Heck, there is even a cross platform Silverlight called Moonlight. Yes, it really is that awesome.

Another advantage to Mono is that you can use free operating systems to build a web server but still use the language and framework that you are used to. This is especially handy if you don’t have the budget to pay for Windows and MSSQL licences to get a website off the ground. Keep in mind that Microsoft did create the awesome BizSpark program which helps eliminate the costs but not indefinitely.

Since Mono works anywhere, you can technically use any system you want to start developing, but if you’re like me, a strictly Windows developer, then I recommend that you use an alternate operating system. Messing with a new operating system can be fun but the real advantage to this is you get a chance to work with something new that you might end up using in the future (for example, MySQL).

Below are a few links that can get you started…

  • Mono: Information about Mono and the different apps available for it. (You might not use this page for installation though…)
  • Wubi – Ubuntu Installer: As good as VirtualBox is, Wubi installs Ubuntu onto your computer without requiring that you format your computer to create additional partitions. Not only that, but Wubi installs Ubuntu in such a way that you still have access to your primary OS’es files – awesome! (thanks to @lazycoder)
  • Mono Develop: Awesome, Open Source IDE that lets you easily write and test Mono code. I won’t say it is as good as Visual Studio but it is really quite good.
  • Installing Software On Ubuntu: This will probably be the weirdest part for a Windows developer. This page has some good information to get you started.

Written by hugoware

November 15, 2009 at 10:20 pm

ERROR: Cacographic Solecism Directive Encountered **

leave a comment »

** Unreadable Error Message Found

I’m pretty picky about user interface with a lot of the projects I work on ranging from the user experience to the design and layout. Ever since I read Steve Krug’s, Don’t Make Me Think, I find myself spending a lot of time reading over the same content again and again trying to simplify them to their shortest possible length.

One section that has always been a focal point for me has been error messages or really any dialog that requires user interaction. However, I’m not just talking about the cryptic, developer designed error messages like ‘IOError Detected!’ or ‘Generic GDI+ Error’ (I especially hate that error).

No, the error messages I’m talking about are messages that don’t really help the user — or error messages that help the user, but too late into the message.

Here is an example from Netflix. It isn’t a bad message but I think that it could be improved.

Netflix Error Message: Playback Timed Out

The Anatomy Of An Error Message

Not all situations are the same but I try to write all of my error messages in the following order.

  1. What happened in a short sentence.
  2. Give the user options and solutions
  3. Explain in slightly more detail what happened but only if the problem may happen again or it helps them understand how to avoid the problem.

What Happened? Few Words Should Say It All — Or Don’t Bother!

I try to stay brief with everything… well, except blog posts, of course. If you’ve visited my latest project CustomWebmail.com then you’ll notice I try to keep everything to a sentence or two. I’ve had a lot of feedback that people like how short and to the point everything is.

Your error message should be the same – short and to the point. Don’t waste a lot of time explaining why it broke or telling them what happened in the background that caused the failure.

In some cases you don’t even need to present the problem as an error message especially if the resolution is simple. The Netflix message is a good example of this. The message feels a lot like an error – but should it? Or should it be presented that this message is the natural result of leaving the page idle?

User Options – Empower The User Quickly

Giving the user the control to fix the problem right away should immediately follow the title of the error – not an explanation of the problem. Include only as many options are really relevant.

I’d even go as far to say that even Yes and No buttons should have a description as well. Explain what the yes and no buttons will do — even if it seems obvious. A button that reads “Yes; Save my document to the server” is much clearer than simply a button that says “Yes” or “OK”.

The Netflix error says to reload the page — manually. Why? Chances are they already have a mouse nearby — why not simply say Click Here To Continue Your Movie! and handle reloading their page when they press the button?

They do offer a suggestion but they don’t offer to do it for you, which I think would improve this box a little more.

Explain The Problem: But Only If It Matters

I’m sure this part would be a point of contention to many people. Often we feel like we need to tell the user what is wrong but also why there was a problem. Clearly, each situation is different, but more often than not I think that the ‘why’ is irrelevant. Here are a few times I think explaining why is important.

  • The user might make the same mistake again (ex. invalid e-mail addresses)
  • The problem might make a user think your service is broken and you need to explain that it is either normal procedure or a problem from somewhere else.
  • To answer why a response is required (ex. input form that wants information a user might not be comfortable in providing)

More or less, if the reason why doesn’t affect the user then you don’t need to share it. If your function SaveUserData() crashes and returns an ‘Unable to save to /Data/Profiles/Users.txt’ error then don’t tell your user. Simply saying ‘We’re sorry – We had a problem saving your information’ is more than enough information to explain why they need to do the same step twice.

My Version

Remember, I like to nitpick this kind of thing. I realize that error messages in my own programs could be improved as well. That said, here is a sample that I think would work better for visitors.

slightly-better

With this message, we are to the point faster and offer a solution to the problem immediately. I also dimmed the error message some and highlighted the actions that could be taken so the user would be drawn to it quickly. I’m sure this message could be improved upon even more but this seems like a good start.

How much time do you spend making your messages as short and as simple as possible?

** The author spends a lot of time reviewing content — but not his own blog — so if you see any typos then please be forgiving 🙂

Written by hugoware

November 8, 2009 at 9:26 pm

Creating CustomWebmail.com – Part 1

with one comment

CustomWebmail.com is a website that allows you to to create a custom login page for your Outlook Web Access by making changes to the colors, logo and layout of the page. This is a series of blog posts that discuss some of the more interesting parts of developing this project.

The Key Parts Of CustomWebmail.com

In order to develop CustomWebmail.com I had solve a few problems…

  • What is the correct address to post logon attempts to?
  • How can I be reasonably certain that the address is correct?
  • How do I create their custom OWA page with the correct colors and logo?
  • What is the best way to convert an theme image into an actual HTML web page?
  • How can I package their content into a single .zip file?

For the next few weeks I’ll be going over all the steps I used to allow visitors to create custom Outlook Web Access pages with this site.

Determine The Correct Address

Now, this part is probably not close to perfect yet. As it turns out OWA isn’t standard across the board. I’m not just referring to OWA 2003 compared to OWA 2007 — but even matching versions can have different setups. With that said, the application still needs to come up with the correct postback URL to for the final rendered page.

Asking the visitor for the correct URL is probably not really a good idea. They might not understand where to look inside the form or what the address should look like. Instead, the application simply asks them for the address of the Outlook Web Access login page and then uses a series of HTTP calls to determine the rest.

string path = "http://webmail.example.com/exchange";
HttpWebRequest request = HttpWebRequest.Create(path) as HttpWebRequest;

request.UserAgent = USER_AGENT;
request.CookieContainer = result._Cookie;

//get the response from the requester
response = request.GetResponse() as HttpWebResponse;
using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
    content = reader.ReadToEnd();
}

//use content to determine form related information
//...

This section of code tells us a few things…

  • Did a server respond to our request?
  • Were we redirected to a different URL?
  • Which level of security was used – http or https
  • If the server doesn’t respond was it really because nothing was there?
  • Does the content contain anything that looks like an Outlook Web Access page?
  • Are we sure that this address will accept our login attempts?

Yikes! Unfortunately those are all real problems that need to be solved in the code — and anything unsuccessful needs to be reported back to the user (or repaired on its own). I’ll skip over the first three since they are fairly easy to determine.

Exception With A Responding Server?

I’ve found that with the HttpWebRequest sometimes you get an exception even if the server is found because the certificate at the site isn’t valid. It throws you off quite a bit especially if you’re expecting a response and your code simply crashes.

As it turns out it isn’t hard to handle invalid certificates.

//Ignore bad certificates
// ** Use at your own risk **
ServicePointManager.ServerCertificateValidationCallback = (obj, cert, chain, ssl) => {
    return true;
};

In my case I’m not too worried if the server’s certificate is valid – I just want to know if it is responding to my requests. By adding in this line of code I can ignore anything invalid and move forward.

Just What Is This Page Anyways?

There are a few arguments you need to use when posting back to an Outlook Web Access login page. We wouldn’t want to accidentally create a login page if someone entered ‘google.com’ instead. By using a couple Regular Expressions we can check to see if the form looks like an Outlook Web Access page.

Here are some of the fields you can check for…

  • An input named username
  • An input named password
  • An hidden input named destination
  • An form action to something containing owaauth.dll

There are more fields you can use but these tend to be a fairly sufficient indicator if we’re looking at an Outlook Web Access form.

Testing The Login

At this point we’re fairly confident that the server we are looking at is an OWA login page but there is one more test we can try. In the final test we perform a fake login to the page to see if we get a password failed error response.

//test the target of the form that was found
HttpWebRequest request = WebRequest.Create(formTarget) as HttpWebRequest;

//create the standard postback information
string post = string.Format(
"username={0}&password={0}&forcedownlevel=0&trusted=0&flags=0&destination={1}&isUtf8=1",
    DateTime.Now.Ticks,
    HttpUtility.UrlEncode(this.Destination)
    );

//prepare the request
request.MaximumAutomaticRedirections = 10;
request.UserAgent = USER_AGENT;
request.Method = "POST";
request.Timeout = 15000;

//and add the content
using (StreamWriter writer = new StreamWriter(request.GetRequestStream())) {
    writer.Write(post);
}

//get the login attempt result
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
response = request.GetResponse() as HttpWebResponse;

//check if a reason code was included
return Regex.IsMatch(response.ResponseUri.Query, @"(&|\?)?reason=\d", RegexOptions.IgnoreCase);

It is possible that we just happened to come across a random server that returns a response code but given all the other tests we can be fairly confident in the address we’re testing.

As a final option we present the user with a test login box that they can try to do a personal verification that the address works.

Written by hugoware

November 2, 2009 at 9:59 pm

Introducing CustomWebmail.com

with 7 comments

I like blogging but the past few weeks (maybe months?) my posts have gotten a little sparse — but for good reason! I’ve been working hard on completing another project and this weekend was the launch date!

What Is CustomWebmail.com?

I do a lot of contract work ranging from programming applications to fixing other in-house developed applications. One job that always gets a lot of interest is customizing a corporate Outlook Web Access login page. I’ve done several of these for a variety of companies.

The idea behind the website was to move the entire customization process online and then present the user with a nice neat .zip file of the resources they would need to install on their webmail server.

customwebmail

How It Was Made

The site uses ASP.NET MVC, C# and jQuery — I couldn’t find a use for my jLinq project, unfortunately :). The site does a lot of interesting things in the code like checking remote sites via HttpWebRequest or creating HTML and image slices using the System.Drawing classes. Over the next few weeks I’ll go over some of the more interesting parts of how the site works.

For now, if you have any Server Admin buddies that might be interested, please tell them about http://www.CustomWebmail.com.

Written by hugoware

November 1, 2009 at 3:08 pm