DBNullable helper – How to handle DBNull gracefully

July 6, 2011

When you use standard .NET readers (e.g. SqlDataReader) to read results from a database operation, NULL values are returned as DBNull, which are not the same as C#’s “null”.

Because data records (even value types) are boxed and treated as objects, you probably want to cast them into their expected type.

SqlDataReader reader = null;

// Code to instantiate the data reader...

int myInt = (int)reader["myInt"];

Unfortunately, this will throw an exception if reader[“myInt”] is DBNull, which can’t be translated into an Int32.

That’s why I often see the following syntax.

// This would work.
int myInt = reader["myInt"] != DBNull.Value ? (int)reader["myInt"] : 0;

// This would also work.
object value;

int myInt = (value = reader["myInt"]) is DBNull ? 0 : (int)value;

// I've seen worse...
int myInt;

try
{
    myInt= (int)reader["myInt"];
}
catch // This will catch the InvalidCastException.  It’s ugly and inefficient.
{
    myInt= 0;
}

My problem with the code samples above is that, even though they achieve the expected result, they look ugly and are hard to read (not to mention the third one, that’s just wrong).

Here comes DBNullable…

using System;

public static class DBNullable
{
    public static TOutput Cast<TOutput>(object value, TOutput defaultValue)
    {
        /* There are other ways to check if an object is a DBNull...
         * - Convert.IsDBNull()
         * - value is DBNull
         * ... but after a quick benchmark, this seems to be the fastest.
         */
        return value == DBNull.Value ? defaultValue : (TOutput)value;
    }

    public static TOutput Cast<TOutput>(object value)
    {
        return Cast(value, default(TOutput));
    }
}

DBNullable is a simple static helper that has two overrides of the same method. Cast() takes an object as the input, and returns either the value cast into the proper type, or a default value if the value was DBNull.

It can be used this way:

int myInt= DBNullable.Cast<int>(reader["myInt"], 0);

And because .NET will infer the type from the second argument most of the time, you can even drop the type specifier.

I find this much more concise and readable.

int myInt= DBNullable.Cast(reader["myInt"], 0);

How to redirect the Console’s output to a TextBox in C#

March 29, 2009

First let’s create a VS Windows Application Project named “ConsoleRedirection”.

In order to redirect the console’s output to a text box in a Windows Form, we need to create a new class based on the abstract StringWriter class.

In the project create a new class file, and name it “TextBoxStreamWriter.cs”. The project now looks like this:

The project's structure

The project's structure

Enter the following code into the .cs file.

using System;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace ConsoleRedirection
{
    public class TextBoxStreamWriter : TextWriter
    {
        TextBox _output = null;

        public TextBoxStreamWriter(TextBox output)
        {
            _output = output;
        }

        public override void Write(char value)
        {
            base.Write(value);
            _output.AppendText(value.ToString()); // When character data is written, append it to the text box.
        }

        public override Encoding Encoding
        {
            get { return System.Text.Encoding.UTF8; }
        }
    }
}

Make sure the abstract “Encoding” property is overridden, and also override the Write(char value) method, which is called when character data is written to the stream.

Now open the main Form class “Form1.cs”, and drag and drop a TextBox and a button into it. Name the TextBox “txtConsole”.

How the Form looks after the UI elements have been added.

How the Form looks after the UI elements have been added.

The last thing to do is to enable the redirection. Double-click on the form to open the code view. The code that needs to be inserted is in bold. As you can see, there is nothing overwhelming.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace ConsoleRedirection
{
    public partial class FormConsole : Form
    {
        // That's our custom TextWriter class
        TextWriter _writer = null;

        public FormConsole()
        {
            InitializeComponent();
        }

        private void FormConsole_Load(object sender, EventArgs e)
        {
             // Instantiate the writer
             _writer = new TextBoxStreamWriter(txtConsole);
             // Redirect the out Console stream
            Console.SetOut(_writer);

            Console.WriteLine("Now redirecting output to the text box");
        }

        // This is called when the "Say Hello" button is clicked
        private void txtSayHello_Click(object sender, EventArgs e)
        {
            // Writing to the Console now causes the text to be displayed in the text box.
            Console.WriteLine("Hello world");
        }
    }
}

The full code for this article is available at http://svanryckeghem.free.fr/downloads/ConsoleRedirection.zip

Saving an image to disk with C#/ASP.NET

March 24, 2009

I received several requests from readers asking me to post an example of saving an image to disk.  So here it is. The following ASP.NET code demonstrates how to save a Bitmap object to a disk location.

using System;

using System.Drawing;
using System.Drawing.Imaging;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // Bitmap object
        Bitmap bmp = new Bitmap(100, 200);  // This is just a black rectangle

        // Save to disk
        string fileName = "C:\\image.jpg";

        bmp.Save(fileName, ImageFormat.Jpeg);

        bmp.Dispose();  // Always make sure the image object is being disposed.
    }
}

Numpad JavaScript Control

December 13, 2008

UPDATE (2010/03/17)

I’ve got a request to randomize the position of the buttons. I’ve updated the download link so it points to the new version.

Enabling the random positioning of the buttons can be achieved by passing an option in the constructor

numPad = new NumpadControl({Randomize: false});

UPDATE END

Numpad JavaScript Control

Working on a web UI project, I found out that it can be annoying, even confusing, to have to abandon the mouse to start entering numbers in a text box.

The form I was building was mostly consisting of drop-down lists, used to narrow down a selection. List boxes are convenient because they can be manipulated with the mouse only. One control in the form required the user to drop the mouse and start typing a numeric value in the box. That’s why I thought it would be a good idea to have a virtual numpad appear next to that box, to allow the user to click the numbers instead of typing them, a bit like a calendar control.

The Numpad JavaScript control in action.

The Numpad JavaScript control in action.

Download the control.

The control has been tested in IE6+, Firefox 3 & Opera 9

How to use:

Here is a sample HTML page containing a text box. The Numpad Control is being attached to that text box when the user clicks it.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <title>Num Pad Control test page</title>
    <script type="text/javascript" src="Controls.js"></script>
    <script type="text/javascript">
    var txtNumber = null;
    var numPad = null;

    window.onload = function ()
    {
        numPad = new NumpadControl();

        txtNumber = document.getElementById("txtNumber");

        txtNumber.onfocus = function ()
        {
            numPad.Show(this);
        }
    }
    </script>
</head>

<body>

<div>
    <input type="text" id="txtNumber" />
</div>

</body>
</html>

Export a movie clip from Flash to an image file using C#/ASP.NET and ActionScript’s BitmapData

October 20, 2007

Update #2 : I fixed another bug where non-square images would not be rendered properly because the height and width were being processed backwards. I fixed the source code in the article, as well as in the ZIP file.

Update #1 : I realized that the ActionScript GetPixel() function doesn’t always return a 6 characters long string, which will cause the pixel data sent to the ASPX page to be corrupted.

Introduction

In this article, I’m going to demonstrate how to export the content of a movie clip from Flash to a JPEG file.

Flash is a great tool that I used for years now. I recently worked on a project involving Flash, and got asked if it was possible to save the content displayed inside Flash to a file. Yes, it’s possible, and actually not very difficult to achieve.

The key element here is to convert the vector graphics to a bitmap, then to get color information for every pixel of that bitmap, and send them to the server where a small program will re-compose the image.

The source code for this article is available for download.

Let’s get started.

Step 1: Create a Flash movie

I created an empty Flash movie (ExportBitmapData.fla), and added some code to its first and unique frame. The code does 3 things:

  • Generate a movieclip and draw some shape in it.
  • Create a BitmapData object and copy the content of the movieclip into it.
  • Send the pixel values to the server by clicking on a button

Please note that you need to manually add a Button component to the library, or it won’t be instanciated.

The first part of the code is about creating variables and calling the functions when the Flash loads:

import flash.display.BitmapData;

var container:MovieClip = null;
var fx:MovieClip = null;
var bmp:BitmapData = null;
var btnExport:mx.controls.Button = null;

function movie_load():Void
{
    // Create a container movieclip
    container = this.createEmptyMovieClip("container", this.getNextHighestDepth());
    // Create a BitmapData object that will hold the copy of the container movieclip
    bmp = new BitmapData(200, 200);
    fx = this.createEmptyMovieClip("fx", this.getNextHighestDepth());

    DrawMovieClip();
    DrawButton();
}

Then there is the method that draws some image as a regular vector graphic, and then creates a copy in the BitmapData object.

function DrawMovieClip():Void
{
    // Draw two overlapping square to the "container" movieclip
    container.clear();
    container.beginFill(0x000000, 50);
    container.moveTo(0,0);
    container.lineTo(200,0);
    container.lineTo(200,200);
    container.lineTo(0,200);
    container.endFill();

    container.beginFill(0x800000, 50);
    container.moveTo(50,50);
    container.lineTo(150,50);
    container.lineTo(150,150);
    container.lineTo(50,150);
    container.endFill();

    fx.clear();

    // copy the movieclip into the BitmapData
    bmp.draw(container);

    fx.attachBitmap(bmp, fx.getNextHighestDepth());
    fx._x = 250;
}

Add a button that will trigger exporting

function DrawButton():Void
{
    btnExport = this.createClassObject(mx.controls.Button, "btnExport", this.getNextHighestDepth(), {label:"Export"});
    btnExport.move(10, 210);
    btnExport.addEventListener("click", ExportBitmap);
}

Create the exporting function, the one that is called when the button is clicked. It works by iterating through each pixel of the BitmapData object, and building a string that contains all the colors value. In this case, the string looks like “8080808080808080808…”. That string is transmitted to the server, and will be processed by C#.

function ExportBitmap(evt:Object):Void
{
    var output:String = "";
    var col = "";
    for(var i:Number=0;i<bmp.height;i++)
    {
        for(var j:Number=0;j<bmp.width;j++)
        {

            col = bmp.getPixel(j,i).toString(16);		

            // In some cases, the color will be truncated (e.g. "00FF00" becomes "FF00")
            // so we are adding the missing zeros.
            while(col.length<6)
            {
                col = "0" + col;
            }
            output+=col;
        }
    }

    // Use a LoadVars to transmit the data to the ASPX page using POST
    var lv:LoadVars = new LoadVars();
    lv.pixels = output;
    lv.height = 200;
    lv.width = 200;

    lv.send("GetPixelData.aspx", "_blank", "POST");
}&#91;/sourcecode&#93;
Then just add a call to the main function
&#91;sourcecode language='jscript'&#93;
movie_load();
stop();&#91;/sourcecode&#93;
If I run the flash movie, here is what I get:<img src="https://saezndaree.files.wordpress.com/2007/10/bitmapdatatransform.gif" alt="Vector movieclip and bitmap copy side by side" />The vector movieclip is on the left, and its bitmap copy is on the right.We now have a way for flash to transmit the image to the server.  Let's look at how these pixel information should be processed on the server-side.
<h2>Part 2: Save the image with ASP.NET</h2>
I created a new Web Project in Visual Studio 2005, and copied the flash files to the project's directory.  The project will contain two web pages, the first one (default.aspx) will contain the flash, while the second (GetPixelData.aspx), will receive the pixel data and gather them to form the image.

The default.aspx page is very simple.  It only contains the code necessary to display the flash object:


<body>
    <form id="form1" runat="server">
    <div>
        <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="550" height="400" id="ExportBitmapData" align="middle">
        <param name="allowScriptAccess" value="sameDomain" />
        <param name="movie" value="ExportBitmapData.swf" /><param name="quality" value="high" /><param name="bgcolor" value="#ffffff" /><embed src="ExportBitmapData.swf" quality="high" bgcolor="#ffffff" width="550" height="400" name="ExportBitmapData" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
        </object>
    </div>
    </form>
</body>

The HTML code for GetPixelData.aspx is even simpler:

<body>
    <form id="form1" runat="server">
    <div>
    <asp:Label ID="lblPixelData" runat="server" />
    </div>
    </form>
</body>

The really intersting part is in its code-behind file, GetPixelData.aspx.cs:

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using System.Drawing;

public partial class GetPixelData : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// Retrieve the pixel data from Flash
string pixelData = Request[“pixels”];

// If there is no data, simply display a message
if (pixelData == null)
{
lblPixelData.Text = “No data available”;
return;
}

//The width and height of the image have been transmitted as well
int width = int.Parse(Request[“width”]);
int height = int.Parse(Request[“height”]);

Bitmap bmp = null;

string curPixelColor = String.Empty;

int x = 0;
int y = 0;

if (pixelData != String.Empty)
{
// Here we create a Bitmap object that has the same size as the one in Flash
bmp = new Bitmap(width, height);

// Iterate through each group of six characters and convert them to a Color
// then assign that color to the pixel of the Bitmap object
for (int i = 0; i < pixelData.Length / 6; i++) { curPixelColor = pixelData.Substring(i * 6, 6); bmp.SetPixel(x,y, ColorTranslator.FromHtml("0x" + curPixelColor)); if(x==width-1) { x = 0; y++; } else { x++; } } } // Set the content type as jpeg Response.ContentType="image/jpeg"; // Save the Bitmap object to the ouput stream, and flush the stream bmp.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg); bmp.Dispose(); Response.End(); } }[/sourcecode] Here is a little summary of what is going on:

  • When the user clicks the “export” button, the pixels from the BitmapData are sent to the GetPixelData.aspx page (which opens in a new window) as a long string. Each color value is a sequence of six characters, representing an hexdecimal value.
  • GetPixelData.aspx reads the string from POST.
  • The program loops through the content of the string, extracting the characters by groups of six.
  • At every iteration, the horizontal pixel position is incremented by one, so we’re moving from left to right, then every time we reach the end of a line, the vertical position is incremented as well.
  • The 6 characters group is converted to a color using the ColorTranslator.FromHtml() method, and its value is assigned to the pixel.
  • We set the content of the page as being a JPEG image and flush the content to send it back to the client.

The result looks like this, the new image has been created and is displayed in the browser:
Bitmap object that is sent back from the server

Conclusion

This is a very primitive example of what can be done to send an image from Flash to the server. We could as well save the content to the disk. The major drawback of saving images in such way is that the server load is pretty big. That technique is therefore not suitable for big images.

The end.

La lumière

September 21, 2007

This is something I wrote a while ago, but I still like it (after a while, I usually hate looking back at my old work). And, yes, it’s in French, sorry for those who won’t understand…

La lumière se rapprochait.

Il ne savait pas combien de temps s’était écoulé depuis qu’il l’avait aperçue pour la première fois. Alors minuscule, imperceptible, elle était maintenant nette.

Il avait peur. Il percevait de terribles grondements au loin et sentait le sol vibrer sous lui par intermittence, comme si un monstre s’apprêtait à émerger des enfers.

Il ne savait pas où il se trouvait et il n’arrivait pas à se rappeler depuis combien de temps il était cloîtré dans cet étrange prison, chaude et humide, inquiétante par son aspect trop familier. Comme s’il y avait passé toute son existence sans même s’en rendre compte.

Une fois de plus, ce qu’il craignait arriva. Les parois autours de lui se rapprochaient, le compressant, le faisant glisser plus près de la lumière. Il était comme aspiré par elle et l’idée de ce qui l’attendait au bout de chemin le terrorisait. Le tonnerre autour de lui était de plus en plus distinct. La fréquence des secousses ne cessait de croître. Il tentait de s’accrocher à quelque chose mais rien ne semblait pouvoir entraver sa terrible chute.

La lumière l’effleurait à présent, froide, agressive. Il voulait retourner dans sa prison, là où il faisait chaud.

Mais la lumière ne voulait pas le laisser partir, elle le saisit et l’attira vers elle. Il était perdu. L’entrave autour de ses jambes était trop puissante. Il lui était impossible de lutter. Il se trouvait à présent entouré par la lumière, à sa merci.

Les grondements avaient cessé.

A leur place, il n’y avait plus qu’un doux battement. Le froid avait également disparu, chassé par un souffle chaud et léger.

Sa peur s’était envolée. Il se sentait bien. Epuisé, il glissait lentement vers le sommeil.

Sous lui, le monde était devenu doux et soyeux.

Alors que la “Bataille pour Bagdad” se terminait et que la fureur des combats s’estompait, un petit Irakien goûtait pour la première fois au délice de s’endormir dans les bras de sa mère.

Sébastien Vanryckeghem

Portfolio: Dombrowski

September 21, 2007

Dombrowski

I drew this character to illustrate a play my friend Dwight wrote.

When parseInt() doesn’t return the expected value

September 20, 2007

Once, I was working on a JavaScript application that required converting time from the US format (hh:mm:ss [AM|PM]). As I had to perform some conversion on the time members, I encountered a weird bug, where the application would return the wrong value, but not always. As I was investigating that bug, I realized that I was not using parseInt() properly.The parseInt function takes one mandatory argument (the string to parse), plus a less known optional argument, that defines which base is used for the conversion.

parseInt(string[, base]);

There is in an implicit rule that defines which base is used when the optional parameter is not specified:

  • Base 10 is the default
  • Base 8 (octal) is used if the string starts with “0”
  • Base 16 (hexadecimal) is used if the string starts with “0x”

The hours and minutes in my application were formatted as HH:MM. Because of the rule above, if you try parsing “07” without specifying the base, it works fine, and returns 7 as expected. However, if you try the same but with “08” instead, the parseInt function will return 0.

To make sure the conversion works every time I had to append the base parameter.

var n = "08";
var octal = parseInt(n); // Returns 0
var decimal = parseInt(n, 10); // Returns 8

It took me some time to figure out why my code was not working, so I thought it would be a good idea to share that tip on my blog.

Portfolio: MC Monitor Splash

September 19, 2007

MC Monitor Splash

Easy SHA1 encryption in C# / ASP.NET

September 19, 2007

The .NET framework has a some useful hidden methods available. One of them is a static method of the FormAuthentication class, from the System.Web.Security namespace, HashPasswordForStoringInConfigFile().

using System;
using System.Web;
using System.Web.Security;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string password = FormsAuthentication.HashPasswordForStoringInConfigFile("password", "SHA1");
        Response.Write(password);
    }
}

This code writes “5BAA61E4C9B93F3F0682250B6CF8331B7EE68FD8” to the page.