Using the log4net AdoNetAppender to log to a bit(boolean) column

By Haan on Tuesday 08 June 2010 16:52 - Comments (6)
Category: log4net, Views: 9.578

Many .Net developers are using log4net as logging framework. To log messages to a MSSQL database, you can use the AdoNetAppender class that is in the log4net framework.

There are many examples of how to implement this appender, so setting up basic logging using the AdoNetAppender is pretty easy. Adding extra string columns is still relatively easy, just add a parameter in the log4net config:

XML:
1
2
3
4
5
6
7
8
<parameter>
       <parameterName value="@myNewParam" />
        <dbType value="String" />
        <size value="50" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%property{myNewParam}" />
        </layout>
</parameter>



(don't forget to create a nvarchar(50) column in the Log table ;) )

Assign text to the property before logging a message to make it actually show up in your log table (this part is a bit harder to find):

C#:
1
2
log4net.GlobalContext.Properties["myNewParam"] = "test";
Logger.Debug("test debug message");



But today I spent a few hours figuring out how to log a boolean value to the Log table. I couldn't find any information on the Internet, so I put in this blog where it may help others who run into the same issue.

The actual solution is off course very simple, once you know to do it ;)
You follow the same procedure as for adding string columns, with the following changes:
- create a bit column in the Log table, for example 'myBooleanParam'
- configure the parameter as follows:

XML:
1
2
3
4
5
6
7
<parameter>
        <parameterName value="@myBooleanParam" />
        <dbType value="Boolean" />        
        <layout type="log4net.Layout.PatternLayout" >
          <conversionPattern value="%property{myBooleanParam}" />
        </layout>
</parameter>



Now you can assign 'true' or 'false' to the myBooleanParam property like in the example above and it will show up as 1 or 0 in the Log table.

Using jQuery in MS Dynamics CRM

By Haan on Wednesday 02 June 2010 16:09 - Comments (8)
Category: Dynamics CRM, Views: 9.365

Introduction
In this blog post, I'll share some experiences that I recently had with using jQuery script in MS Dynamics CRM 4.0 forms. For those not familiar with MS Dynamics CRM and / or customizing forms, this blog post will not be very interesting.

A little introduction first. I was asked if it would be possible to re-arrange fields on a CRM form. More specifically, re-arrange address fields to reflect the address layout of the country that is selected. I knew that a former collegue had tried to do the same, but couldn't get it working, but that was before jQuery was available ;)

After writing this blog post, I realize it has gotten rather large and still misses some detailed background information. I may split this post into separate parts in the future.
Getting started
After delivering a little Proof of Concept page, I started developing the javascript. In this blog I'll explain about the process, hopefully it helps and / or inspires others (and maybe I'll get some feedback about how to do things better too ;) )

The first thing that we need to do, is to inject a script reference to the jQuery script into the form's <header> tag. I used the method explained in this blogpost for that. There are other ways, for example load the script with the Eval() function as explained here, but I think injecting a script tag is cleaner (Eval() is Evil after all ;) )

After this we're ready to go!
The environment
In my specific case, I used the customeraddress entity. On the form is a dropdown list with countries. When a country is selected, the layout (5 possibilites) is determined in the script.
To be able to set different layouts, I created a 5 x 3 grid, with a number of 'whitespace' fields, that can be used to create empty spaces and are hidden with a line of jQuery script. Within this grid the fields can be set to any location. Let me show the end result first:

This the form when it opens to create a new record:
http://tweakers.net/ext/f/JWn5mIpHaBY9on76YSa1xnh5/full.png

See how the layout has changed to reflect the selected country:
http://tweakers.net/ext/f/5tPW5vSIjWg1Xuh8m1BQr78o/full.png
Show me the magic!
Now the interesting part, the actual scripts!

First to be able to determine where each field needs to be set, I defined a two-dimensional array for each layout:

JavaScript:
1
2
3
4
5
6
7
// define different formats as multi-dimensional arrays representing the layout on the form
layout1 = new Array(new Array(streetname, buildingNumber, numberSuffix),
                    new Array(line1, whitespace3, whitespace4),
                    new Array(line2, whitespace5, whitespace6),
                    new Array(postalcode, city, stateOrProvince),
                    new Array(whitespace7, whitespace8, whitespace9),
                    new Array(whitespace10, whitespace11, whitespace12));



Notice that I use Visual Studio to be able to have IntelliSense support for javascript in general and jQuery in specific.

The function for hiding the whitespaces is as follows:

JavaScript:
1
2
3
4
HideWhiteSpaces = function ()
{    
    $("td[id*='whitespace']").hide();
}



Thusfar things are not too complicated. But now we're ready to shuffle the fields on the form to reach to desired layout. An important thing to notice is that is not possible to just remove the fields and then place them back in the right order, because this breaks some CRM scripts that are attached to all fields on CRM forms. This means that we have to switch fields until we have the desired layout. Special care is needed when fields moved to another row, because you need to leave at least one field on a row, or else you will have no reference to that row anymore.

Another important thing to know, is how a CRM form is built. Let me show how this looks in the IE Developer tool:
http://tweakers.net/ext/f/Guvrg4xqOvQeYIRv2yXqhi5x/full.png

As you can see, each line is a table row, and each label / input field element is wrapped in a <td> element.

So to be able to move a field, we have to get a jQuery reference first, and then move both the input and the label elements.

JavaScript:
1
2
3
4
5
6
7
GetjQueryParentContainer = function (fieldName)
{
    return $("input[id=" + fieldName + "]").parent();
}

var line1Field = GetjQueryParentContainer("line1");
var line1Label = line1Field.prev();



Moving field "line2" before "line1" can now be done as follows:

JavaScript:
1
2
3
4
5
// here we use the insertBefore() function, 
// in other cases you may want to use insertAfter()
// for many cases, both are possible to achieve the same result
line2Field.insertBefore(line1Label);
line2Label.insertBefore(line2Field);



Well that's pretty much it, everything else is just repeating and combining the steps above, until the new layout is set.

In my current script all layouts are achieved through hard-coded steps, because it turned out to be very difficult to do it automatically, especially when you have to deal with fields that are moved to another row. I hope to fix that in the future.

update
I forgot an important script that fixes the tab index after a layout has changed:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
SetTabIndex = function ()
{
    var tabindex = 1;
    $('input').each(function ()
    {
        if (this.type != "hidden")
        {
            $(this).attr("tabindex", tabindex);
            tabindex++;
        }
    });
}