Gigi Labs

Please follow Gigi Labs for the latest articles.

Saturday, November 30, 2013

VB .NET Basics: Conditionals, Logical Operators and Short-Circuiting

Hello again! :)

Two months ago, I wrote the article "VB .NET Basics: Input and Output", which has recently been gaining a lot of attention. In today's article, we're going to see how we can write conditional statements in VB .NET to let the program take different actions depending on user input. More importantly, we're going to see how to use logical ANDs and ORs in 'If' conditions - something that is likely to catch you off guard if you're coming from some other language.

First, create a new VB .NET Console Application. If you're using SharpDevelop, the project will be created with the following initial code:

Module Program
    Sub Main()
        Console.WriteLine("Hello World!")
       
        ' TODO: Implement Functionality Here
       
        Console.Write("Press any key to continue . . . ")
        Console.ReadKey(True)
    End Sub
End Module

Let's start off with a simple conditional. Replace the code in Main() wit the following:

        Console.WriteLine("Are you male or female?")
        Dim genderStr As String = Console.ReadLine();

This just asks the user about his/her gender and collects their input in a string. Now, we'll use that input as follows:

        If genderStr.Substring(0, 1).ToLower() = "m" Then
            Console.WriteLine("Hello sir!")
        End If

We're taking the first character from the user's input (thanks to the Substring() method), converting it to lowercase. That way, whether the user types "Male", "male", or "m126", it's still going to interpret that as being male.

There are a couple of things to note here. First of all, in VB .NET, the = operator (which is the same one used in assigning values to variables) is used for equality comparison. This is quite different from C-like languages which use = for assignment and == for comparison.

Secondly, VB .NET is sensitive to spacing. If you try to put the Then on the next line, like this:

        If genderStr.Substring(0, 1).ToLower() = "m"
            Then
            Console.WriteLine("Hello sir!")
        End If

...you'll get a syntax error. You can, however, stuff the conditional in one line and omit the End If, like this:

        If genderStr.Substring(0, 1).ToLower() = "m" Then Console.WriteLine("Hello sir!")

Okay, since the feminists must be grumbling at this point, let's replace our conditional with this:

        If genderStr.Substring(0, 1).ToLower() = "m" Then
            Console.WriteLine("Hello sir!")
        ElseIf genderStr.Substring(0, 1).ToLower() = "f" Then
            Console.WriteLine("Hello miss!")
        Else
            Console.WriteLine("Hello alien!")
        End If

You might be familiar with Else from other languages, but this ElseIf might possibly be new. ElseIf makes its condition (the one checking for female) run only if the initial If returned false - it's the equivalent of writing the following:

        If genderStr.Substring(0, 1).ToLower() = "m" Then
            Console.WriteLine("Hello sir!")
        Else
            If genderStr.Substring(0, 1).ToLower() = "f" Then
                Console.WriteLine("Hello miss!")
            Else
                Console.WriteLine("Hello alien!")
            End If
        End If

...but when you have lots of conditions, it saves you from having to indent indefinitely. ElseIf exists in other languages, but can vary quite a lot between them (e.g. elif in Python, elsif in Perl, or even just else if in the C-like languages).

Of course, when we are checking the same variable over different values, we know we should actually be using a Select Case statement, which is the equivalent of a switch statement in C# and other C-like languages. We can change the above conditional into a Select Case as follows:

        Select Case genderStr.Substring(0, 1).ToLower()
            Case "m":
                Console.WriteLine("Hello sir!")
            Case "f":
                Console.WriteLine("Hello miss!")
            Case Else
                Console.WriteLine("Hello alien!")
        End Select

Select Case is syntactically quite different from switch statements. In particular, there are no break statements, and Case Else is the equivalent of the default statement in C-like languages: its statements are executed if none of the earlier cases are matched.

We can now add the following to wait for user input before exiting the application:

        Console.ReadLine()

...and then test it (I used Ctrl+F5 to run, instead of debug, the application - this lets you run several instances at the same time):


Now, let's see how to write more interesting conditional statements. To do this, let us first collect the user's age:

        Dim message As String = Nothing
        Dim ageStr As String = Console.ReadLine()
        Dim age As Integer = 0
        Dim converted As Boolean = Integer.TryParse(ageStr, age)

So, first we're declaring a message variable, which we'll set in a minute. It's initially set to Nothing, which is equivalent to C# null. Then we're accepting user input, and converting it to a number. We use Integer.TryParse() so that if the conversion fails, it simply returns false and age is not set - this saves us from having to do exception handling as in "C# Basics: Arithmetic and Exceptions".

You might guess that we can logically combine conditional statements using the And and Or statements. Let's try that out:

        If converted Then
            If genderStr.Substring(0, 1).ToLower() = "m" And age < 30 Then
                message = "You are a young man!"
            ElseIf genderStr.Substring(0, 1).ToLower() = "m" And age >= 30 Then
                message = "You are an old man!"
            ElseIf genderStr.Substring(0, 1).ToLower() = "f" And age < 30 Then
                message = "You are a young lady!"
            ElseIf genderStr.Substring(0, 1).ToLower() = "f" And age >= 30 Then
                message = "You are an old lady!"
            ElseIf genderStr.Substring(0, 1).ToLower() = "a" Then
                message = "Whatever your age, you are an alien."
            End If
        End If

Heh, if you're 30 or over, you're probably shaking your fists. But anyway, since we're dealing with multiple variables, we can't use a Select Case statement here. Instead, we are checking different combinations of gender and age. Note that I haven't included an Else statement, and this means that if the age conversion fails, then message remains Nothing.

Now, let's show the message. We can handle the case where message is Nothing with another conditional:

        If message IsNot Nothing And message.Length > 0 Then
            Console.WriteLine(message)
        End If

Okay. Let's begin testing the application:


That worked pretty well, didn't it? Now let's try an invalid age:


Uh oh. What just happened here? Despite the check against Nothing, accessing message.Length still caused a NullReferenceException to be thrown. Why is that? Let's look at our condition again:

         If message IsNot Nothing And message.Length > 0 Then

If message is Nothing, then the first condition resolves to false. At this point we normally expect the second expression to be ignored (which is called short circuiting), but that is not what is happening. The And operator evaluates both expressions, and only then ANDs them together.

In other words, we're using the wrong operator. We need to use AndAlso instead of And, and OrElse instead of Or. AndAlso and OrElse will short circuit (i.e. they won't evaluate both expressions if they don't have to), while And and Or are bitwise operators and mean something different (which we won't go into at this stage). If you're coming from any C-style language such as C#, then you can understand this as follows: AndAlso and OrElse are the equivalents of && and || respectively; while And and Or are the equivalents of & and | respectively.

We can now change our code to use AndAlso instead of And:

        If converted Then
            If genderStr.Substring(0, 1).ToLower() = "m" AndAlso age < 30 Then
                message = "You are a young man!"
            ElseIf genderStr.Substring(0, 1).ToLower() = "m" AndAlso age >= 30 Then
                message = "You are an old man!"
            ElseIf genderStr.Substring(0, 1).ToLower() = "f" AndAlso age < 30 Then
                message = "You are a young lady!"
            ElseIf genderStr.Substring(0, 1).ToLower() = "f" AndAlso age >= 30 Then
                message = "You are an old lady!"
            ElseIf genderStr.Substring(0, 1).ToLower() = "a" Then
                message = "Whatever your age, you are an alien."
            End If
        End If
       
        If message IsNot Nothing AndAlso message.Length > 0 Then
            Console.WriteLine(message)
        End If

And now, this code doesn't raise any exceptions (there is no message written because that's the way the logic works):


Great. In this article, we learned how to use conditional statements in Visual Basic .NET. We started by looking at simple If and Select Case statements, and then discovered how to set up more complex conditions by using Boolean operators to combine simple conditions. The main takeaway from this is that you should always use AndAlso and OrElse in your conditions, not And and Or. This will allow your conditions to short circuit, i.e. if your condition is (A AND B) and A is false, then the condition is false regardless of the value of B, so B is not evaluated. Short circuiting is very important when the second condition is dependent on the first, as we have seen in the above code.

Monday, November 25, 2013

C# WCF: A Minimal Client and Server Using Visual Studio 2012

Hey there! :)

In this article we'll be taking a brief look at how to set up a very simple WCF client and server. We're actually going to let Visual Studio generate the server, and see how we can interact with it. WCF allows us to create applications that communicate remotely with one another - for instance, a client can call a method on a remote server and obtain the result. To follow along, you'll need a version of Visual Studio from 2008 onwards. Sadly, you can't do this in SharpDevelop.

To start off, set up a new WCF Service Library:


You'll notice that Visual Studio has generated some files for us, but let's worry about those later. For now, press F5. When you do that, this program comes up:


This WCF Test Client is actually a program that is communicating with our service (the one autogenerated by Visual Studio). We can see that there is this service at a particular URL on localhost:8733. This service is exposing a couple of methods, one of which is GetData(). Both methods are part of an interface (called a contract) called IService1. If you double-click on GetData(), you can see a Request section at the top, which shows the input parameters it can take.

Let's change the Value of the value parameter from 0 to 35, and then hit the Invoke button. If you get the following security warning, just click OK:


Once you click Invoke, the Response section at the bottom shows the return value, and echoes your input:


Let us now take a look at how this works. Our service exposes the two methods we have seen via the IService1 interface, and the Service1 class which implements it:


Notice how the IService1 interface is adorned with the ServiceContract attribute, and its methods are adorned with the OperationContract. That's how a WCF service exposes its functionality; a client will talk to the server through this interface. We'll see that in a moment. But first, let's take a look at how the service is configured. If you open the App.config file, you'll notice there is quite a bit of configuration in there:


The important things to notice at this stage are the base address and the endpoints. The base address shows the URL where the service is being hosted, and it's the same URL that clients will connect to. The endpoints, on the other hand, define how clients will connect to the service. In this case we have two endpoints: a basic HTTP binding which is used when a client connects to the base address, and which uses the IService1 interface as a contract. If you read more about WCF, you'll find these endpoints referred to as ABC (address, binding, contract). The other endpoint, mex, is a metadata exchange feature by which clients can discover what a server has to offer - that's how the WCF Test Client we used earlier manages to discover the functionality offered by our service.

If you are thinking that the configuration file looks complicated, that's understandable. Fortunately, however, you don't have to edit it by hand. If you right click on App.config, and select Edit WCF Configuration...


...then you can use this handy editor to set things up as you like:


When you press F5 and run the service, it's actually being hosted inside this WCF Service Host, that you can access from the System Tray:


The WCF Test Client, on the other hand, is being invoked via a command line argument. You can see this if you right click on the project, select Properties, and then select the Debug tab, you'll see the following:


Now, let's see how we can actually communicate with our service without using the WCF Test Client. First, copy the service URL (by default it's http://localhost:8733/Design_Time_Addresses/CsWcfMinimal/Service1/). Add a new project (Console Application) to the solution; this project will act as the client. Once that is done, right click on References and select Add Service Reference...:


Enter the service URL in the Address field and hit Go:


Notice the Namespace field is set to ServiceReference1 by default - we'll use this in a minute to identify the service from the client code. Press OK. This generates a bunch of code in the background that makes life easier for the client. In fact, let us now write some code in the client's Main() method to use the service. We start off by creating a client using the code generated by the service reference:

            ServiceReference1.IService1 service = new ServiceReference1.Service1Client();

If you click on Service1Client() and press F12 (Go to Definition), you'll be able to see the service reference code that was so conveniently generated for you:


...and if you open the client's App.config file, you'll see that the endpoint has been set up for us:


Let's get back to the code. All we have left to do is use the methods we want to use. Here's the full code for the client's Main() method:

        static void Main(string[] args)
        {
            ServiceReference1.IService1 service = new ServiceReference1.Service1Client();
            String response = service.GetData(5);
            Console.WriteLine(response);

            Console.ReadLine();
        }

Now, since the service is still your startup project, press Ctrl+F5 to run it without debugging. Once that is up and running, start the client either via the appropriate context menu option (see screenshot below), or by setting it up as the startup project and then pressing F5.


Rejoice, for it works:


Lovely! :) In this article, we explored the sample WCF Service Library project that is provided when you start a new project of that type. We saw how it is hosted in the WCF Service Host, and how we can interact with it via the WCF Test Client, which is launched by means of a command line argument. We also learned how to consume it from a client program, by first adding a service reference based on the service URL, and then using the handy autogenerated code to invoke the methods on the service.

We didn't actually make any funky server functionality though - we simply used that provided in the project. If you want to try your hand at writing your own service, Mahak Gupta's "A Simple Example of WCF Service" is a great article showing how you can make a simple WCF calculator service.

SDL2: Loading Images with SDL_image

Welcome!

[Update 2015-11-14: This article is out of date. Check out the latestversion at Gigi Labs.]

In the previous article, "SDL2: Displaying an Image in the Window", we saw how we could load bitmaps using the SDL_LoadBMP() function. Unfortunately, working with bitmaps is very limiting, and the core SDL2 library does not provide the means to work with other image formats. However, such functionality is provided by an extension library called SDL_image. In this article, we will learn how to set up SDL_image and also how to use it to load other image formats.

Setting up SDL_image is not very different from setting up SDL 2.0 itself. You need to go to the SDL_image homepage and download the development libraries and runtime binaries:


Let's concentrate on those development libraries for the moment. Once you extract the contents of the zip file, you'll be able to find an include folder and a lib folder among other stuff. The include folder contains a single header file, SDL_image.h. This needs to go into your C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\SDL2 folder (this is for Visual Studio 2010; you may need to change the v7.0A part depending on the version you're using), or wherever your other SDL2 header files are located, and drop the SDL_image.h file there.

As for the lib folder, whatever is in the x86 subfolder goes into the C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Lib folder, and whatever is in the x64 subfolder goes into C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Lib\x64.

With that done, let's set up a new project using Visual Studio 2010. Create an Empty Project from the Visual C++ category. Right click on the project and select Properties. In Configuration Properties -> Linker -> System, change the SubSystem to Windows (/SUBSYSTEM:WINDOWS). Then go to Input (also under Linker) and replace the Additional Dependencies with the following:

SDL2.lib;SDL2main.lib;SDL2_image.lib

You'll notice this is a little different from "SDL2: Setting up SDL2 in Visual Studio 2010" in that we've added the SDL2_image.lib. Since this is a new library, we need to link it into our program to use its functionality.

Now let's try some code. Add a file called main.cpp, and let's start off with the following code (it's the same as that used in "SDL2: Displaying an Image in the Window", without the error checking to keep it concise, and also filling the window):
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>

int main(int argc, char ** argv)
{
    bool quit = false;
    SDL_Event event;

    SDL_Init(SDL_INIT_VIDEO);

    SDL_Window * window = SDL_CreateWindow("SDL2 Displaying Image",
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
    SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);
    SDL_Surface * image = SDL_LoadBMP("image.bmp");
    SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer,
        image);

    while (!quit)
    {
       SDL_WaitEvent(&event);

       switch(event.type)
       {
       case SDL_QUIT:
           quit = true;
           break;
       }

       SDL_RenderCopy(renderer, texture, NULL, NULL);
       SDL_RenderPresent(renderer);
    }

    SDL_DestroyTexture(texture);
    SDL_FreeSurface(image);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

Now, we're going to load this nice photo (.jpg format) taken in Gardaland in 2006:


Doing this is quite simple. First, we initialise SDL_image by calling IMG_Init() right after the call to SDL_Init():
    IMG_Init(IMG_INIT_JPG);
...and before the call to SDL_Quit(), we shut down SDL_Image using IMG_Quit():

    IMG_Quit();
All we have left to do now is replace the line calling SDL_LoadBMP() with one that uses IMG_Load() instead:
    SDL_Surface * image = IMG_Load("PICT3159.JPG");
You should now be able to build this program (Ctrl+Shift+B). Before you run it, though, make sure that SDL2.dll is in the same folder as your executable. You'll also need to toss in all the DLLs from the runtime binaries package (most likely the x86 one is what you'll be using by default) - that includes SDL2_image.dll along with format-specific files such as libjpeg-9.dll, libpng16-16.dll, etc. If you're going to run from Visual Studio, make sure the image is in the same folder as your main.cpp file; otherwise if you're running straight from the executable, the image should be in the same folder with it.

And voilà:


Isn't that sweet? The SDL_image library allows you to load a large variety of image formats, by just replacing SDL_LoadBMP() with IMG_Load(). You'll need to initialise and cleanup the library (although it seems to work even without this) and remember to link the library and include the appropriate header file. But as you can see, it's pretty straightforward.

Sunday, November 17, 2013

SDL2: Displaying an Image in the Window

Hello! :)

[Update 2015-11-14: This article is out of date. Check out the latestversion at Gigi Labs.]

In this article we're going to learn how to load a bitmap image from disk and display it in an SDL2 window. In order to follow along, you'll need to set up a project to work with SDL (see "SDL2: Setting up SDL2 in Visual Studio 2010"), and start off with the basic empty window code from SDL2: Empty Window, which is this:

    #include <SDL2/SDL.h>        
            
    int main(int argc, char ** argv)        
    {        
        bool quit = false;        
        SDL_Event event;        
            
        SDL_Init(SDL_INIT_VIDEO);        
            
        SDL_Window * screen = SDL_CreateWindow("My SDL Empty Window",
            SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480,
            0);        
            
        while (!quit)        
        {        
           SDL_WaitEvent(&event);        
            
           switch(event.type)        
           {        
           case SDL_QUIT:        
               quit = true;        
               break;        
           }        
        }        
            
        SDL_Quit();        
            
        return 0;        
    }

Build the application. Remember to place SDL2.dll into your bin\Debug folder. The empty window should appear if you run the application, and you should be able to close it by clicking on the "X" at the top-right corner.

Let's first change the window declaration a little bit (I changed the name of the variable and the window title):

    SDL_Window * window = SDL_CreateWindow("SDL2 Displaying Image",
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);

After that, let's create an SDL_Renderer:

    SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);

We use SDL_CreateRenderer() to get an instance of SDL_Renderer. This renderer represents the output device (usually your graphics card) to which your code will be drawing. In fact it's the final destination of our image, because we'll be following the steps below:


SDL_CreateRenderer() takes three parameters. The first is the window where we are drawing. The second allows us to select different rendering drivers; in our case we don't care, and we can set it to -1 and get the default one. The last parameter allows us to set SDL_RendererFlags to control how the rendering occurs. We can set it to zero to default to hardware rendering. If any of this sounds confusing, don't worry about it and just use SDL_CreateRender() as it is here.

We can now load the image from disk using the SDL_LoadBMP() function, which takes a path to a bitmap and loads it into an SDL_Surface:

    SDL_Surface * image = SDL_LoadBMP("image.bmp");

I'm using the following photo of the Grand Harbour in Valletta, Malta, which I took back in 2005, and which has a width of 320 pixels and a height of 240 pixels:


Place the image in your bin\Debug folder, where your executable is located.

Next, we need to create a texture.

    SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer,
        image);

A texture is memory close to the graphics card (see image below), and we use SDL_CreateTextureFromSurface() to directly map our surface (which contains the image we loaded) to a texture.


Now that we have a texture, let's display it in the window. At the end of the while loop, just after the switch statement, add the following:

        SDL_RenderCopy(renderer, texture, NULL, NULL);
        SDL_RenderPresent(renderer);

We use SDL_RenderCopy() to copy the texture to the output device. There are also a couple of other parameters that we're setting to NULL - more on these in a minute. Finally, SDL_RenderPresent() is what commits the texture to the video memory, displaying the image.

Before we run the program, we must always remember to clean up every resource that we initialise. In our case, that means adding the following just before the call to SDL_Quit():

    SDL_DestroyTexture(texture);  
    SDL_FreeSurface(image);  
    SDL_DestroyRenderer(renderer);  
    SDL_DestroyWindow(window);

If you now run the program from within Visual Studio, surprisingly enough, you get a blank window:


...whereas if you run the program directly from the executable in your solution's bin\Debug folder (where image.bmp is also located), it works:


We'd know more about what's going on if we had proper error handling in place. With every call to the SDL2 API, we should be checking the return values, and displaying an error if any of them fail. SDL_ShowSimpleMessageBox() is great for displaying simple error messages, while SDL_GetError() gives us the actual error text of the last thing that failed. Let's refactor our initialisation code to check for errors and display them:

    SDL_Window * window = SDL_CreateWindow("SDL2 Displaying Image",
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
    if (window == NULL)
        SDL_ShowSimpleMessageBox(0, "Window init error", SDL_GetError(),
            window);
    SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);
    if (renderer == NULL)
        SDL_ShowSimpleMessageBox(0, "Renderer init error",
            SDL_GetError(), window);
    SDL_Surface * image = SDL_LoadBMP("image.bmp");
    if (image == NULL)
        SDL_ShowSimpleMessageBox(0, "Image init error", SDL_GetError(),
            window);
    SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer,
        image);
    if (texture == NULL)
        SDL_ShowSimpleMessageBox(0, "Texture init error",
            SDL_GetError(), window);

When we run this code, the first error we get is the following:


That's it - the program can't find the image. Remember how it worked when running from the executable, but not from Visual Studio? That's because Visual Studio starts at a different directory. As a quick workaround, just copy image.bmp into your source folder (where main.cpp is located). Hit F5, and it now works:


Fantastic! The image is right there in the window! But... can you see what happened? The image, which has dimensions 320x240, has been stretched to fill the window, which has dimensions 640x480. That's sometimes convenient, because we get scaling for free. However, it makes photos look messy. Let's change our call to SDL_RenderCopy() to fix this:

        SDL_Rect dstrect = { 5, 5, 320, 240 };
        SDL_RenderCopy(renderer, texture, NULL, &dstrect);

Remember those two parameters at the end of SDL_RenderCopy() that we were setting to NULL? If you look at the documentation for SDL_RenderCopy(), you'll see that the last one defines a destination region (which part of the texture will the image be copied to). If it's set to NULL, then the image is stretched to fill the texture - which is what happened above.

By setting dstrect (the last parameter), we can render to only a portion of the window. We set it to an SDL_Rect, with x and y set to 5, and width and height corresponding to the dimensions of the image. When we run the program, we get this:


Excellent! :) In this article we looked at how to create renderers, surfaces and textures. We used these to load bitmaps and display them on the screen. A glimpse into error handling allowed us to troubleshoot issues with loading the image from Visual Studio. Finally, we saw the difference between copying the image to a region of the window, and making it fill the entire window.

I hope you enjoyed this. Come back for more! :)

Saturday, November 16, 2013

C# EF: Setting Connection Strings at Runtime with Entity Framework 5.0, Database First, VS2012

Hi everyone! :)

This article deals with how to solve the problem of building and setting an Entity Framework connection string at runtime, based on a database-first approach (i.e. you have generated an Entity Data Model based on an existing database). You are expected to be familiar with ADO .NET and the Entity Framework. The first part of the article deals with setting up an Entity Data Model and simple interactions with it; this should appeal to all readers. The second part deals with the custom connection string issue, and will be helpful only to those who have actually run into that problem.

We're going to be using Visual Studio 2012, and Entity Framework 5.0. Start a new Console Application so that you can follow along.

Setting up the database


You can use whatever database you want, but in my case I'm using SQL Server Compact edition (SQLCE). If you're using something else and already have a database, you can just skip over this section.

Unlike many of the more popular databases such as SQL Server and MySQL, SQLCE is not a server and stores its data in a file with .sdf extension. This file can be queried and updated using regular SQL, but is not designed to handle things like concurrent users - something which isn't a problem in our case. Such file-based databases are called embedded databases.

If you have Visual Studio, then you most likely already have SQLCE installed. Look for it in "C:\Program Files (x86)\Microsoft SQL Server Compact Edition\v4.0". Under the Desktop or Private folders you'll find a file called System.Data.SqlServerCe.dll which we need to interact with SQLCE. Add a reference to it from your Console Application.

Now, we're going to create the database and a simple one-table schema. We'll use good old ADO.NET for that. We'll create the database only if it doesn't exist already. First, add the following usings at the top of Program.cs:

using System.IO;
using System.Data.SqlServerCe;

In Main(), add the following:

            String filename = "people.sdf";
            String connStr = "Data Source=" + filename;

Since SQLCE works with just a file, we can create a basic connection string using just the name of the file we're working with.

The following code actually creates the database and a single table called person.

            try
            {
                // create database if it doesn't exist already

                if (!File.Exists(filename))
                {
                    // create the actual database file

                    using (SqlCeEngine engine = new SqlCeEngine(connStr))
                    {
                        engine.CreateDatabase();
                    }

                    // create the table schema

                    using (SqlCeConnection conn = new SqlCeConnection(connStr))
                    {
                        conn.Open();

                        String sql = @"create table person(
                                       id int identity not null primary key,
                                       name nvarchar(20),
                                       surname nvarchar(30)
                                   );";

                        using (SqlCeCommand command = new SqlCeCommand())
                        {
                            command.CommandText = sql;
                            command.Connection = conn;
                            int result = command.ExecuteNonQuery();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

We first use SqlCeEngine to create the database file. Then we use ADO .NET to create the person table. Each row will have an auto-incrementing id (primary key), as well as a name and surname. Note that SQLCE does not support the varchar type, so we have to use nvarchar (Unicode) instead.

If you now build and run the application, you should find a people.sdf file in the bin\Debug folder. We'll use that to create an Entity Data Model for the Entity Framework.

Creating the Data Model


Right click on the project and select Add -> New Item...:


From the Data category, select ADO.NET Entity Data Model. You can choose a name for it, or just leave it as the default Model1.edmx; it doesn't really matter.


Click The Add button. This brings up the Entity Data Model Wizard.


The "Generate from database" option is the default selection, so just click Next.


Hit the New Connection... button to bring up the Connection Properties window.


If SQL Server Compact 4.0 is not already selected as the Data source, click the Change... button and select it from the Change Data Source window:


Back in the Connection Properties window, click the Browse... button and locate the people.sdf file in your bin\Debug folder that we generated in the previous section. Leave the Password field empty, and click Test Connection. If all is well, you'll get a message box saying that the test succeeded.

Once you click OK, the Entity Data Model Wizard should become populated with a connection string and a default name for the model:


When you click Next, you'll get the following message:


Just click Yes and get on with it. In the next step, import the person table into your model by ticking the checkbox next to it:


Click Finish. The files for your model are added to the project. You may also get the following warning:


You don't have to worry about it. Just click OK. If you click Cancel instead, you won't have the necessary autogenerated code that you need for this project.

Interacting with the database using the Entity Framework


After the database-creation code from the first section, and before the end of the try scope, add the following code:

                // interact with the database

                using (peopleEntities db = new peopleEntities())
                {
                    db.people.Add(new person() { name = "John", surname = "Smith" });
                    db.SaveChanges();

                    foreach (person p in db.people)
                    {
                        Console.WriteLine("{0} {1} {2}", p.id, p.name, p.surname);
                    }
                }

Here, we create an instance of our entity context (peopleEntities) and then use it to interact with the database. We add a new row to the person table, and then commit the change via db.SaveChanges(). Finally, We retrieve all rows from the table and display them.

Also, add the following at the end of the Main() method so that we can see the output:

            Console.ReadLine();

Run the program by pressing F5. The output shows that a row was indeed added:


The Entity Framework knows where to find the database because it has a connection string in the App.config file:

  <connectionStrings>
    <add name="peopleEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlServerCe.4.0;provider connection string=&quot;data source=|DataDirectory|\people.sdf&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>

This might be good enough in some situations, but other times, we might want to build such connection string in code and ask the Entity Framework to work with it. A reason for this might be because the connection string contains a password, and you want to obtain it from an encrypted source. The following two sections illustrate how this is done.

Building a raw Entity Framework connection string


Let's start out by commenting out the connection string in the App.config file:

  <connectionStrings>
    <!--
    <add name="peopleEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlServerCe.4.0;provider connection string=&quot;data source=|DataDirectory|\people.sdf&quot;" providerName="System.Data.EntityClient" />
    -->
  </connectionStrings>

If you try running the program now, you'll get a nice exception.

Now, what we want to do is add the connection string into our code and pass it to the entity context (the peopleEntities). So before our Entity Framework code (which starts with using (peopleEntities...), add the following:

                String entityConnStr = @"metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlServerCe.4.0;provider connection string=&quot;data source=|DataDirectory|\people.sdf&quot;";

If you now try to pass this connection string to the peopleEntities constructor, you'll realise that you can't. You can see why if you expand Model1.edmx and then Model1.Context.tt in Solution Explorer, and finally open the Model1.Context.cs file:


The peopleEntities class has only a parameterless constructor, and it calls the constructor of DbContext with the connection string name defined in App.config. The DbContext constructor may accept a connection string instead, but we have no way of passing it through peopleEntities directly.

While you could add another constructor to peopleEntities, it is never a good idea to modify autogenerated code. If you regenerate the model, any code you add would be lost. Fortunately, however, peopleEntities is a partial class, which means we can add implementation to it in a separate file (see this question and this other question on Stack Overflow).

Add a new class and name it peopleEntities. Add the following at the top:

using System.Data.Entity;

Implement the class as follows:

    public partial class peopleEntities : DbContext
    {
        public peopleEntities(String connectionString)
            : base(connectionString)
        {

        }
    }

We can now modify our instantiation of peopleEntities to use our connection string as defined in code:

using (peopleEntities db = new peopleEntities(entityConnStr))

Since we are using a partial class defined in a separate file, any changes to the model will cause the autogenerated peopleEntities to be recreated, but will not touch the code we added in peopleEntities.cs.

When we run the program, we now get a very nice exception (though different from what we got right after commenting out the connection string in App.config):


Apparently this happens because of the &quot; values, which are necessary in XML files but cause problems when supplied in a String literal in code. We can replace them with single quotes instead, as follows:

                String entityConnStr = @"metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlServerCe.4.0;provider connection string='data source=|DataDirectory|\people.sdf'";

If we run the program now, it works fine, and a new row is added and retrieved:


Using EntityConnectionStringBuilder


You'll notice that the connection string we've been using is made up of three parts: metadata, provider, and the provider connection string that we normally use with ADO.NET.

We can use a class called EntityConnectionStringBuilder to provide these values separately and build a connection string. Using this approach avoids the problem with quotes illustrated at the end of the previous section.

First, remove or comment out the entityConnStr variable we have been using so far.

Then add the following near the top of Program.cs:

using System.Data.EntityClient;

Finally, add the following code instead of the connection string code we just removed:

                EntityConnectionStringBuilder csb = new EntityConnectionStringBuilder();
                csb.Metadata = "res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl";
                csb.Provider = "System.Data.SqlServerCe.4.0";
                csb.ProviderConnectionString = "data source=people.sdf";
                String entityConnStr = csb.ToString();

When you run the program, it should work just as well:


Summary


This article covered quite a bit of ground:
  • We first used the SqlceEngine and ADO .NET to create a SQL Server Compact database.
  • When then created an Entity Data Model for this database.
  • We added some code to add rows and retrieve data using the Entity Framework.
  • We provided the Entity Framework with a raw connection string in code. To do this, we used a partial class to add a new constructor to the entity context class that can pass the connection string to the parent DbContext. We also observed a problem with using &quot; in the connection string, and solved it by using single quotes instead.
  • We used EntityConnectionStringBuilder to build a connection string from its constituent parts, and in doing so completely avoided the &quot; problem.
I hope you found this useful. Feel free to leave any feedback in the comments below. Check back for more articles! :)

Monday, November 11, 2013

C# Security: Securing Passwords by Salting and Hashing

Hello and welcome, dear readers! :)

This article deals with storing passwords securely... usually in a database, but to keep things simple, we'll just use a C# dictionary instead. As part of this article, we'll cover two interesting techniques called salting and hashing. These topics can sometimes be challenging to understand - in fact you can see from my question about salting on StackOverflow that it had taken me a while to understand the benefits of salting, but it doesn't have to be that way. I am writing this article to hopefully make this fascinating subject easy to understand.

Right, so let's get to business. Create a new Console Application using SharpDevelop or whichever IDE you prefer. Add the following near the top, so that we can use dictionaries:

using System.Collections.Generic;

Just inside your class Program, before your Main() method, add the following dictionary to store our users and their corresponding passwords (see "C# Basics: Morse Code Converter Using Dictionaries" if this seems in any way new to you):

        public static Dictionary<String, String> users = new Dictionary<String, String>()
        {
            { "johnny""password" },
            { "mary""flowers" },
            { "chuck""roundhousekick" },
            { "larry""password123" }
        };

It is now pretty simple to add a method that can check whether a given username and password result in a successful login:

        public static bool Login(String username, String password)
        {
            if (users.ContainsKey(username) && users[username] == password)
                return true;
            else
                return false;
        }

This code first checks that the username actually exists in the dictionary, and then checks whether the corresponding password matches.

We can now test this code by replacing the contents of Main() with the following code:

        public static void Main(string[] args)
        {
            Console.Write("Username: ");
            String username = Console.ReadLine();
          
            Console.Write("Password: ");
            Console.ForegroundColor = ConsoleColor.Black;
            String password = Console.ReadLine();
            Console.ResetColor();
          
            bool loggedIn = Login(username, password);
            if (loggedIn)
                Console.WriteLine("You have successfully logged in!");
            else
                Console.WriteLine("Bugger off!");
          
            Console.ReadLine();
        }

Notice that when requesting the password, we're setting the console's text colour to black. The console's background colour is also black, so the password won't show as you type, fending off people trying to spy it while looking over your shoulder.

Press F5 to try it out:


Awesome - we have just written a very simple login system.

The problem with this system is that the passwords are stored as clear text. If we imagine for a moment that our usernames and passwords were stored in a database, then the actual passwords can easily be obtained by a hacker gaining illegal access to the database, or any administrator with access to the database. We can see this by writing a simple method that shows the users' data, simulating what a hacker would see if he managed to breach the database:

        public static void Hack()
        {
            foreach (String username in users.Keys)
                Console.WriteLine("{0}: {1}", username, users[username]);
        }

We can then add the following code just before the final Console.ReadLine() in Main() to test it out:

            Console.WriteLine();
            Hack();

This gives us all the details, as we are expecting:


This isn't a nice thing to have - anyone who can somehow gain access to the database can see the passwords. How can we make this better?

Hashing


One way is to hash the passwords. A hash function is something that takes a piece of text and transforms it into another piece of text:


A hash function is one-way in the sense that you can use it to transform "Hello" to "8b1a9953c4611296a827abf8c47804d7", but not the other way around. So if someone gets his hands on the hash of a password, it doesn't mean that he has the password.

Another property of hash functions is that their output changes considerably even with a very small change in the input. Take a look at the following, for instance:



You can see how "8b1a9953c4611296a827abf8c47804d7" is very different from "5d41402abc4b2a76b9719d911017c592". The hashes bear no relationship with each other, even though the passwords are almost identical. This means that a hacker won't be able to notice patterns in the hashes that might allow him to guess one password based on another.

One popular hashing algorithm (though not the most secure) is MD5, which was used to produce the examples above. You can find online tools (such as this one) that allow you to compute an MD5 hash for any string you want.

In order to use MD5 in our code, we'll need to add the following statement near the top of our program code:

using System.Security.Cryptography;

At the beginning of the Program class, we can now create an instance of the MD5 class to use whenever we need:

         private static MD5 hashFunction = MD5.Create();

If you look at the intellisense for MD5, you'll see that it has a ComputeHash() method, which returns an array of byte, rather than a String:


We're going to do some String work, so add the following near the top:

using System.Text;

Let's write a little helper method to hash our passwords, using Strings for both input and output:

        public static String Hash(String input)
        {
            // code goes here
        }

In this method, the first thing we need to do is convert the input String to a byte array, so that ComputeHash() can work with it. This is done using the System.Text.Encoding class, which provides several useful members for converting between Strings and bytes. In our case we can work with the ASCII encoding as follows:

            byte[] inputBytes = Encoding.ASCII.GetBytes(input);

We can then compute the hash itself:

            byte[] hashBytes = hashFunction.ComputeHash(inputBytes);

Since we don't like working with raw bytes, we then convert it to a hexadecimal string:

            StringBuilder sb = new StringBuilder();
            foreach(byte b in hashBytes)
                sb.Append(b.ToString("x2").ToLower());

The "x2" bit converts each byte into two hexadecimal characters. If you think about it for a moment, hexadecimal digits are from 0 to f (representing 0-15 in decimal), which fit into four bits. But each byte is eight bits, so each byte is made up of two hex digits.

Anyway, after that, all we need to do is return the string, so here's the entire code for the method:

        public static String Hash(String input)
        {
            byte[] inputBytes = Encoding.ASCII.GetBytes(input);
            byte[] hashBytes = hashFunction.ComputeHash(inputBytes);
          
            StringBuilder sb = new StringBuilder();
            foreach(byte b in hashBytes)
                sb.Append(b.ToString("x2").ToLower());
          
            return sb.ToString();
        }

We can now change our database to use hashed passwords:

        public static Dictionary<String, String> users = new Dictionary<String, String>()
        {
            { "johnny"Hash("password") },
            { "mary"Hash("flowers") },
            { "chuck"Hash("roundhousekick") },
            { "larry"Hash("password123") }
        };

In this way, we aren't storing the passwords themselves, but their hashes. For example, we're storing "5f4dcc3b5aa765d61d8327deb882cf99" instead of "password". That means we don't store the password itself any more (if you ever signed up to an internet forum or something, and it told you that your password can be reset but not recovered, you now know why). However, we can hash any input password and compare the hashes.

In our Login() method, we now change the line that checks username and password as follows:

             if (users.ContainsKey(username) && users[username] == Hash(password))

Let's try this out (F5):


When the user types "johnny" as the username and "password" as the password, the password is hashed, giving us "5f4dcc3b5aa765d61d8327deb882cf99". Since the passwords were also stored as hashes in our database, it matches. In reality our login is doing the same thing as it was doing before - just that we added a hash step (a) when storing our passwords and (b) when receiving a password as input. Ultimately the password in our database and that entered by the user both end up being hashes, and will match if the actual password was the same.

How does this help us? As you can see from the hack output (last four lines in the screenshot above), someone who manages to breach the database cannot see the passwords; he can only get to the hashes. He can't login using a hash, since that will in turn be hashed, producing a completely different value that won't match the hash in the database.

Although hashing won't make the system 100% secure, it's sure to give any potential hacker a hard time.

Salting


You may have noticed that in the example I used, I had some pretty dumb passwords, such as "password" and "password123". Using a dictionary word such as "flowers" is also not a very good idea. Someone may be able to gain access to one of the accounts by attempting several common passwords such as "password". These attempts can be automated by simple programs, allowing hackers to attempt entire dictionaries of words as passwords in a relatively short period of time.

Likewise, if you know the hash for common passwords (e.g. "5f4dcc3b5aa765d61d8327deb882cf99" is the hash for "password"), it becomes easy to recognise such passwords when you see the expected hash. Hackers can generate dictionaries of hashes for common passwords, known as rainbow tables, and find hashes for common words used as passwords.

We can combat such attacks by a process known as salting. When we compute our hashes, we add some string that we invent. This means changing the first line of our Hash() function as follows:

            byte[] inputBytes = Encoding.ASCII.GetBytes("chuck" + input);

Both the database password and the one entered by the user will be a hash of "chuck" concatenated with the password itself. When the user tries to login, it will still work, but look at what happens now:


The login worked, but the hashes have changed because of the salt! This means that even for a password as common as "password", a hacker cannot identify it from the hash, making rainbow tables much less effective.

Summary


This article described how to store passwords securely. It started off by doing the easiest and worst thing you can do: store them as clear text. A hash function was subsequently introduced, to transform the passwords into text from which the password cannot be retrieved. When a user logs in, the hash of the password he enters is compared with the password hash stored in the database.

Finally, the hashes were salted, by adding an arbitrary piece of text to them, in order to transform the hashes into different values that can't be used to identify common passwords.

I hope this made password security a little easier to understand. Please come back again, and support us by sharing this article with your friends, buying games from GOG.com, or any of the other ways described in the "Support the Ranch" page.