Archive

Archive for the ‘Programming’ Category

Localizing SpecFlow

December 28th, 2011 No comments

On a recent usergroup meeting I got introduced to SpecFlow. This opened a whole new world in formulating tests ans specifications. Although I’ve been trying to formulate my tests in a BDD manor, inspired by JP Boodhoo’s and Stefan Liesern’s BDD examples this feels much better.

So the next logical step would be to move to a natural german specification instead of having the original given-when-then syntax.

Turns out, that switching the language is actually really easy. Even though I didn’t seem to find anything on the web … You just have to adjust the app.config like this

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="specFlow"
      type="TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler,
            TechTalk.SpecFlow"/>
  </configSections>
  <specFlow>
    <language feature="de-DE" tool="" />
  </specFlow>
</configuration>

And that’s all that’s to it.

Categories: Programming, Uncategorized Tags: ,

Parameterized queries in MySQL

November 22nd, 2011 No comments

In order to do SQL right in the .Net world, you just don’t concaternate a search-term with a static search-string, because this will open all gates to SQL-injection. So the following schould not be used:

MySqlConnection connection = new MySqlConnection(_connectionString);
MySqlCommand command = connection.CreateCommand();
command.CommandText = "SELECT * FROM Forum where name = '" + forumName + "'";

Instead you should use a parameterized query. Easy, you might say. Just add a placeholder to the SQL-statement and off you go.

MySqlConnection connection = new MySqlConnection(_connectionString);
MySqlCommand command = connection.CreateCommand();
MySqlParameter forumNameParameter = new MySqlParameter("@forumName", forumName);
command.Parameters.Add(forumNameParameter);
command.CommandText = "SELECT * FROM Forum where name = @forumName";

Unfortunatly this doesn’t seem to work alright. At least I didn’t get any results, even though my search-term did exist.

Looking at the actual SQL that was being executed on the server something became obvious.

SELECT * FROM Forum where name = @forumName

That’s not the SQL I was expecting. Somehow the parameter was not being substitued by the actual value. But why?

Just a short test: the same code does work on a MS-SQL database!

Solution

@ is not a valid character for a placeholder in MySQL. Instead  ? should be used. The correct code should look like this:

MySqlConnection connection = new MySqlConnection(_connectionString);
MySqlCommand command = connection.CreateCommand();
MySqlParameter forumNameParameter = new MySqlParameter("?forumName", forumName);
command.Parameters.Add(forumNameParameter);
command.CommandText = "SELECT * FROM Forum where name = ?forumName";

So this finally worked.

Categories: Programming Tags: ,

Mass-Updating Active Directory

May 3rd, 2011 No comments

I just love PowerShell! Although I’m not really mature in the syntax yet, I find myself moreoften doing little things in powershell.

Today I figured, that in my previous task of creating 150 sample accounts I missed out on the email-address. So I just wrote a simple line of powershell. First off, I went to the OU just by navigating to the AD-provider cd AD: and then change to cd OU=Test,DC=demo,DC=local. That’s already cool. Then just a simple line like

dir | foreach { $x = Get-AdUser $_; $y=$x.samAccountName; Set-Aduser -identity $x -emailaddress "$y@demo.local"; }

And since I’m on a roll, I also updated the passwords for all users

Get-ADUser -Filter 'Name -like "*"' -SearchBase "OU=Acme,DC=demo,DC=local" | Set-ADAccountPassword -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "demo" -Force)
Categories: Programming Tags:

Sample Domain Data

April 16th, 2011 No comments

Sometimes you just need to have a decent amount of sample data. Recently I created an active directory to do some development using SharePoint 2010. In order to have a realistic baseline I needed to have a decent amount of fictive users.

So instead of creating a ton of users like User1 to User150 I thought of something more elaborate. Why not create random user-accounts?

After some google-research I found a blogpost with a list of first- and lastnames as CSV-files. Fantastic! This looks like a promising starting point. To spice everything up a notch I also created list of departments and functions. So this will give me quite a batch of user-data.

To mix everything quite good, I created a little piece of powershell:

# Import list of Last names from Simple Text file
$lastname=import-csv '.\lastname.csv'
# Import list of First names Simple Text file
$firstname=import-csv '.\firstname.csv'
# Import list of roles, prefixes and departments
$roles=import-csv '.\role.csv'
$prefixs=import-csv '.\prefix.csv'
$departments=import-csv '.\department.csv'
# How many names to generate
$totalnames=150
# the Header for our new CSV file
$firstline='Firstname,Lastname,Position,Department,Phone'
# Create a file called “DomainUsers.csv”
Set-content -path 'DomainUsers.csv' -value $firstline
$firstnamecount=$firstname.Count
$lastnamecount=$lastname.Count
$rolecount=$roles.Count-1
$prefixcount=$prefixs.Count-1
$departmentcount=$departments.Count-1
# Go through and Generate some names
foreach ( $namecounter in 1..$totalnames )
{
    # Pick a random first and Last name
    $lastnamenumber=(get-random -min 0 -max ($lastnamecount-1))
    $firstnamenumber=(get-random -min 0 -max ($firstnamecount-1))
    $rolenumber=(get-random -min 0 -max ($rolecount))
    $prefixnumber=(get-random -min 0 -max ($prefixcount))
    $departmentnumber=(get-random -min 0 -max ($departmentcount))
    $FakeName=($firstname[$firstnamenumber].Firstname+','+$lastname[$lastnamenumber].Lastname)+','+
        ($prefixs[$prefixnumber].Prefix+' '+$departments[$departmentnumber].Department+' '+$roles[$rolenumber].Role).Trim()+','+
        $departments[$departmentnumber].Department+','+
        '555-'+(get-random -min 100 -max 999)+'-'+(get-random -min 1000 -max 9999)
    # Echo the New name to the Screen
    write-host $fakename
    # and write to the File
    add-content -path 'DomainUsers.csv' -value $fakename
}

I think the script doesn’t need any further explanation. The result will be a CSV-file with a bunch of random user account data.

The Import into active directory is done in a second powershell-script (just because I had that already).

param([string]$FileName, [string]$adpath)
Import-Module ActiveDirectory
function Import-Users([string]$UserFile)
{
    Import-Csv $UserFile | foreach-object {
        $accountName = $_.Lastname+$_.Firstname.Substring(0,2)
        $displayName=$_.Firstname+" "+$_.LastName
        New-AdUser $accountName -samAccountName $accountName -Company "Acme Corp." -Department $_.Department -DisplayName $displayName -GivenName $_.Firstname -Surname $_.Lastname -OfficePhone $_.Phone -Title $_.Position -CannotChangePassword $true -PasswordNeverExpires $true -Enabled $true -AccountPassword (ConvertTo-SecureString -AsPlainText "demo" -Force) -Path $spou
    }
}
$spou = "OU=Acme,$adpath"
Import-Users $FileName

This is rather boring. To start the script you have to supply the name of the CSV containing the user-data and you have to supply the path to your domain in the form of “dc=acme,dc=local”. This snipplet assumes that there is an OU called Acme, where all the user accounts should be placed.

These are the files I used to generate the sample accounts:

Categories: Programming Tags:

Full Screen Mode in VMWare

April 2nd, 2011 No comments

I just setup a new VM using a Windows 2008 R2 server to do some SharePoint 2010 development. To really get started I switched my VM to fill-screen-mode, in order to get more desk-space.

But that just gave me a blank, black screen. Resizing the window works perfectly fine, but not full-screen. Even manually triggering the “fit client” event didn’t do anything good.

The solution was trivial (as usual with this kind of errors): you have to enable 3D acceleration in the VM settings. What a bummer.

Categories: Programming Tags: ,

Logging from multiple processes

February 6th, 2011 No comments

When logging with log4net to a file (using the FileAppender), the FileAppender is holding an exclusive lock on the file. This doesn’t cause any problems, not even when the application is running with multiple threads, because log4net should be thread-safe.

This does change however when working with multiple processes, that all share a common log4net configuration and thus all will utilize the same FileAppender. In this case there should not be an exclusive lock by any process. Fortunately log4net has an appropriate configuration-setting.

<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />

But acquiring and release locks is quite costly and thus will slow down the overall performance of the application.

An alternative would be to create an individual log per processes. Luckily log4net supports the expansion of variables to generate log-filenames, so we can add the process-id to the filename-pattern.

<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender,log4net">
    <file type="log4net.Util.PatternString" value="Log[%processid]" />
[...]
</appender>
Categories: .Net Tags:

Exponention in c#

January 17th, 2011 No comments

To compute 10 to the power 2 shouldn’t be any problem

int result = 10 ^ 2;

As if! Visual Studio strongly believes that the result of this computation should be 8. Damn! ^ is a reserved symbol in c# for bitwise exclusive or (XOR). The correct way to computer this would be

int result = Math.Pow(10, 2);
Categories: .Net Tags:

Logging in NHibernat 3.0

January 16th, 2011 No comments

With the release of NHibernate 3.0 the way NHibernate handles logging is changed. Up to 2.1.2 NHibernate used log4net exclusive for logging. The usage of log4net was directly tied into each class of NHibernate.

Now this has been decoupled. NHibernate 3.0 introduces a LoggingProvider. So instead of

private static readonly ILog log = LogManager.GetLogger(typeof (Loader));

a new logger is created using

private static readonly IInternalLogger log = LoggerProvider.LoggerFor(typeof (Loader));

Even though this might not seem like a big deal, there is more to the LoggingProvider. The logging provider currently only supports log4net (well, and a NoLoggingLoggerFactory). In order to determine whether log4net is available for logging, the LoggingProvider looks in the current SearchPath of BaseDirectory of the AppDomain like this:

// look for log4net.dll
string baseDir = AppDomain.CurrentDomain.BaseDirectory;
string relativeSearchPath = AppDomain.CurrentDomain.RelativeSearchPath;
string binPath = relativeSearchPath == null ? baseDir : Path.Combine(baseDir, relativeSearchPath);
var log4NetDllPath = Path.Combine(binPath, "log4net.dll");

What go me started was the fact, the my log4net configuration wasn’t creating any log-output, and I was extremely puzzled on why. I checked my config a dozen times without any error. This was working perfectly fine when working with NHibernate 2.1.2.

After looking at the LoggingProvider and the way logging is initialized it struck me: my log4net assembly is located in the GAC – the the lookup for log4net isn’t detecting my log4net assembly! Changing the properties of the reference to log4net to Copy Local resolved this issue.

Categories: .Net Tags:

Supressing Messages from FXCop

January 8th, 2011 No comments

In a recent project I rellay nailed the code using FXCop. The goal was to eliminate all messages of FXCop.

After a short periode of time I already figure: no way! There are just a couple of cases, where I have to irgnore the messages of FXCop. Luckily there is an easy way to supress the messages of FXCop. Just open the context menu of the message and copy the message as SupresseMessage to the clipboard.

suppress_messages

Next you can insert that at the appropriate position within your code, most likely as a method-attribute.

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes")]

OK, so now your’re good to go. The next run of FXCop should present you a lot less messages.

And if not? Something went wrong. Some little, very well hidden comment in the documentations says:

The ConditionalAttribute is applied to this class, specifying the preprocessing symbol “CODE_ANALYSIS” as the conditional symbol that determines whether the attribute call is included or omitted. If the symbol is defined, the attribute call is included; otherwise, the call is omitted.

OK. So opening up the project properties and adding the symbol CODE_ANALYSIS helped a lot in getting the number of FXCop messages down.

Categories: .Net Tags:

Warmup of Application-Pools

January 3rd, 2011 No comments

Starting with IIS 7.5 (Windows 7, Windows 2008 R2) application pools can be started with the help of an IIS module. This module issues web-requests whenever a new worker-process is being started. This eliminitates the need for additional warmup-scripts.

A more detailed describtion on how to use this module can be found at Using the IIS Application Warm-Up Module.

Categories: IIS, Programming Tags: