Monday, June 14, 2010

JavaScript syntax error with telerik.grid.min.js

When implementing custom binding with the Telerik ASP.NET MVC, I based my code on this example described here under the Controller tab.

The CustomBinding action is called when the whole page is loaded or refreshed, then showing on the grid the default data, e.g. the first page. This action should return a view with the model object (IEnumerable<Order> in this example).

The _CustomBinding action is called from an AJAX call when the user clicks on the grid controls, like page number, sort, or filter. This action should return a view with a GridModel object and not with the view model (IEnumerable<Order>). If you do not use a GridModel object, then you will get the JavaScript syntax error char 4048 in telerik.grid.min.js.




Although the Telerik example is right, when I wrote my code based on it, I mistakenly used the wrong model object, and couldn't figure out what was wrong. Thanks for this forum post that enlighted me of what was going on.

Saturday, June 12, 2010

Using SyntaxHighlighter (version 2.1.364) with Blogger

After spending sometime to make SyntaxHighlighter work with Blogger, I finally found an article that has the solution that perfectly worked for me. The other posts I found were not using the latest version (version 2.1.364 when this post was published), so no support for latest languages such as PowerShell, or they were using the latest version but the instructions didn't work 100%.The following article worked for me:

Wednesday, June 09, 2010

Checking the type and size of RAM with Windows PowerShell

I subscribe to the PowerTip of the day email of PowerShell.com and I got this tip today. If you want to know the type and size of RAM your PC uses, and available banks, you can use the following script:

$memorytype = "Unknown", "Other", "DRAM", "Synchronous DRAM", "Cache DRAM",
"EDO", "EDRAM", "VRAM", "SRAM", "RAM", "ROM", "Flash", "EEPROM", "FEPROM",
"EPROM", "CDRAM", "3DRAM", "SDRAM", "SGRAM", "RDRAM", "DDR", "DDR-2"
$formfactor = "Unknown", "Other", "SIP", "DIP", "ZIP", "SOJ", "Proprietary",
"SIMM", "DIMM", "TSOP", "PGA", "RIMM", "SODIMM", "SRIMM", "SMD", "SSMP",
"QFP", "TQFP", "SOIC", "LCC", "PLCC", "BGA", "FPBGA", "LGA"
$col1 = @{Name='Size (GB)'; Expression={ $_.Capacity/1GB } }
$col2 = @{Name='Form Factor'; Expression={$formfactor[$_.FormFactor]} }
$col3 = @{Name='Memory Type'; Expression={ $memorytype[$_.MemoryType] } }

Get-WmiObject Win32_PhysicalMemory | Select-Object BankLabel, $col1, $col2, $col3


The output would be something like:

BankLabel                     Size (GB) Form Factor         Memory Type
---------                     --------- -----------         -----------
                                      2 DIMM                DDR-2
                                      2 DIMM                DDR-2
                                      2 DIMM                DDR-2
                                      2 DIMM                DDR-2

It works pretty nice, doesn't it?

Monday, May 24, 2010

MVC Music Store and Chinook Database

The MVC Music Store is a sample application built on ASP.NET MVC Framework 2. It includes the source code and a tutorial explaining the steps to build it. This is a great tutorial if you want to get started on ASP.NET MVC 2. When I looked at the documentation, I noticed that the data used by the application is very familiar. Jon Galloway, the author, mentioned on this post that the MVC Music Store data is based on the Chinook Database. The Chinook Database was built using my iTunes library as sample data, and that is why I recognized some particular artists and albums: a mix of rock, heavy metal, classical music and Brazilian music.
As to the Chinook Database I have a list of improvements to be done and need to get sometime to work on a new release. I am also thinking about adding support to document-oriented databases such as Raven DB and MongoDB.

Saturday, November 28, 2009

Setting Assembly Version with Windows PowerShell

I've been using the Build Version Increament add-in for Visual Studio to automatically set the assembly and file versions. It works fine, however, it only works when using the Visual Studio IDE and it requires you to setup every single project of your solution. If you need to increment the assembly version on an automated build (MS Build, NAnt, PSake), then a PowerShell script would be a better solution.

The following script, SetVersion.ps1, searches for AssemblyInfo.cs files in the current directory and its sub directories, and then updates the AssemblyVersion and AssemblyFileVersion. You can optionally provide the version number to use, or it will auto generate one for you. You can customize the Generate-VersionNumber function to use your own version schema. Also, if you are using a source control that needs to check-out files before editing them, such as TFS and Perforce, then add the check-out command to the Update-AssemblyInfoFiles function.

#-------------------------------------------------------------------------------
# Displays how to use this script.
#-------------------------------------------------------------------------------
function Help {
    "Sets the AssemblyVersion and AssemblyFileVersion of AssemblyInfo.cs files`n"
    ".\SetVersion.ps1 [VersionNumber]`n"
    "   [VersionNumber]     The version number to set, for example: 1.1.9301.0"
    "                       If not provided, a version number will be generated.`n"
}

#-------------------------------------------------------------------------------
# Generate a version number.
# Note: customize this function to generate it using your version schema.
#-------------------------------------------------------------------------------
function Generate-VersionNumber {
    $today = Get-Date
    return "1.0." + ( ($today.year - 2000) * 1000 + $today.DayOfYear )+ ".0"
}
 
#-------------------------------------------------------------------------------
# Update version numbers of AssemblyInfo.cs
#-------------------------------------------------------------------------------
function Update-AssemblyInfoFiles ([string] $version) {
    $assemblyVersionPattern = 'AssemblyVersion\("[0-9]+(\.([0-9]+|\*)){1,3}"\)'
    $fileVersionPattern = 'AssemblyFileVersion\("[0-9]+(\.([0-9]+|\*)){1,3}"\)'
    $assemblyVersion = 'AssemblyVersion("' + $version + '")';
    $fileVersion = 'AssemblyFileVersion("' + $version + '")';
    
    Get-ChildItem -r -filter AssemblyInfo.cs | ForEach-Object {
        $filename = $_.Directory.ToString() + '\' + $_.Name
        $filename + ' -> ' + $version
        
        # If you are using a source control that requires to check-out files before 
        # modifying them, make sure to check-out the file here.
        # For example, TFS will require the following command:
        # tf checkout $filename
    
        (Get-Content $filename) | ForEach-Object {
            % {$_ -replace $assemblyVersionPattern, $assemblyVersion } |
            % {$_ -replace $fileVersionPattern, $fileVersion }
        } | Set-Content $filename
    }
}

#-------------------------------------------------------------------------------
# Parse arguments.
#-------------------------------------------------------------------------------
if ($args -ne $null) {
    $version = $args[0]
    if (($version -eq '/?') -or ($version -notmatch "[0-9]+(\.([0-9]+|\*)){1,3}")) {
        Help
        return;
    }
} else {
    $version =  Generate-VersionNumber
}

Update-AssemblyInfoFiles $version


And finally, before running this script, or any PowerShell script, make sure that you are allowed to execute scripts by running Get-ExecutionPolicy. If it returns Restricted, you need to run the following command:

Set-ExecutionPolicy RemoteSigned

Download the entire script from here.

Enjoy it!

Tuesday, November 17, 2009

The Channel 9 Learning Center

If you want to learn the latest Microsoft technologies such as V2010 and .NET 4.0, Windows Azure, and SharePoint 2010, then check it out the training course available at Channel 9 Learning Center:

http://channel9.msdn.com/learn/

Monday, October 12, 2009

Creating a SharePoint List Parent / Child Relationship – Out of the Box

I just came across this article about creating SharePoint lists with parent/child relationship using out-of-the-box functionality:

http://www.endusersharepoint.com/2009/10/02/creating-a-sharepoint-list-parent-child-relationship-out-of-the-box/

Sunday, June 28, 2009

Unit Testing CRM Plug-ins

What is a CRM plug-in?

A plug-in is custom business logic that you can integrate with Microsoft Dynamics CRM 4.0 to modify or augment the standard behavior of the platform. This custom business logic can be executed based on a message pipeline execution model called Event Execution Pipeline. A plug-in can be executed before or after a MS CRM platform event. For example, you can create a plug-in to validate the attributes of an account entity before the create and update operations.

To create plug-ins, you need to create a normal .NET class library and reference the MS CRM SDK libraries. Then add a class that implements the Microsoft.Crm.Sdk.IPlugin interface.
public interface IPlugin
{
    void Execute(IPluginExecutionContext context);
}

Plug-in Unit Testing

In order to write unit tests for your plug-in, you need to create at least a mock of the IPluginExecutionContext. Depending on your plug-in implementation, you will also need to mock ICrmService or IMetadataService if you are calling IPluginExecutionContext.CreateCrmService or IPluginExecutionContext.CreateMetadataService.

There is the MS CRM Plug-in Debugger, which consists of a small EXE container that implements a mock of the IPluginExecutionContext interface. You could use this container to unit test your plug-ins. However, IMHO, I do not see any advantage in using it versus a unit test and a mock framework. I posted a comment on the CRM Team Blog: Testing CRM Plug-in asking about that, but didn't get a response yet.

To unit test a CRM plug in, you can use your favorite unit test framework (NUnit, MbUnit, Visual Studio Tests) and your favorite mock framework (Rhino Mocks, NMock, Typemocks). In this article, I will be using NUnit and RhinoMocks.

The Plug-in Code

In the following example, adapted from the "Programming Microsoft Dynamics CRM 4.0" book, the plug-in validates the account number attribute before saving the account entity.
public class AccountNumberValidator : IPlugin
{
    public void Execute(IPluginExecutionContext context)
    {
        var target = (DynamicEntity) context.InputParameters[ParameterName.Target];

        if (target.Properties.Contains("accountnumber"))
        {
            var accountNumber = target["accountnumber"].ToString();
            var regex = new Regex("[A-Z]{2}-[0-9]{6}");

            if (!regex.IsMatch(accountNumber))
            {
                throw new InvalidPluginExecutionException("Invalid account number.");
            }
        }
    }
}

The code above checks to see if the account number attribute is in the right format. If not, it throws an InvalidPluginExecutionException. Since we will register this plug-in as a pre-event of creating and updating the account entity, this exception will be handled by the CRM platform, and the create/update operation is aborted.

Writing the Plug-in Unit Test

The following code is a simple test using NUnit to verify that an InvalidPluginExecutionException is thrown when the account entity has invalid account number:

[Test]
[ExpectedException(typeof(InvalidPluginExecutionException))]
public void ShouldHandleInvalidAccountNumber([Values("",
                                                    "AB123456",
                                                    "A123456",
                                                    "ABC123456",
                                                    "AB-12345",
                                                    "AB123456",
                                                    "AB-123",
                                                    "AB-1234",
                                                    "aa-012345",
                                                    "aa-000000",
                                                    "Za-999999",
                                                    "wW-936187")]
                                                    string number)
{
    // Create necessary mocks for the plug-in.
    var mocks = new MockRepository();
    var context = mocks.DynamicMock<IPluginExecutionContext>();

    // Creates a property bag for the plugin execution context mock.
    var target = new DynamicEntity();
    target.Properties["accountnumber"] = number;
    var inputParameters = new PropertyBag();
    inputParameters.Properties[ParameterName.Target] = target;

    // Set expectations of mocks.
    Expect.Call(context.InputParameters).Return(inputParameters).Repeat.Any();
    mocks.ReplayAll();

    // Test the plug-in using the context mock.
    IPlugin plugin = new AccountNumberValidator();
    plugin.Execute(context);

    // Verify all the mocks.
    mocks.VerifyAll();
}

Now, we will go through all the details of this unit test:
  • The ExpectedException attribute defines the type of exception that this test expects to be raised. In our case, it is an InvalidPluginExecutionException.
  • This is a parameterized test that uses the Values attribute to define a set of invalid account numbers. This test will run once for each value that we define. The Values attribute is specific to NUnit, but other frameworks have similar mechanisms: MbUnit uses RowTest for example.
  • We create a mock of the IPluginExecutionContext interface by using the MockRepository.DynamicMock method. We are using a DynamicMock because we are only interested in a small piece of the functionality (InputParameters property of the context object). If we want a complete control of the mock object behavior, then we would use a StrickMock. For more information about the types of mocks that you can create with Rhino Mocks, see here.
  • The InputParameters property of the plug-in context, is a property bag that will contain the account number attribute. So, we create this property bag, and add the account number defined by the Values attribute parameter.
  • Now, we set the expectations of the mock object. This step is called the Record state. When the InputParameters property is called, we expect it to return the property bag we created on the previous step. Note that we are using Repeat.Any() that means this property can be called more than once. In our test, we just want to make sure that InputParameters is called, no matter how many times.
  • The Record state is finish by calling ReplayAll(). This will move to the Replay state.
  • Now, we are ready to instantiate our plug-in object and call its Execute method using the plug-in context mock object.
  • Finally, we call VerifyAll() method, to verify that the mock expectations were satisfied. In our case, it will make sure that InputParameters property was called during the Replay state.
This test will assert that the plug-in Execute method will throw an InvalidPluginExecutionException with the account number values supplied.

We also should write a test to assert that no InvalidPluginExecutionException is thrown when using valid account numbers. I will not include this test here, but you can see it on the solution source code files.

Mocking the ICrmService Interface

In our previous test, we only need to mock the plug-in context interface. However, in more complex plug-ins, you might need to mock other interfaces such as the ICrmService. The CreateCrmService method of the IPluginExecutionContext creates an ICrmService object. If you use the CreateCrmService method on your plug-in, you will need to create a mock of ICrmService.

Our validate account number plug-in has been changed to also detect duplicate account numbers. If an account number already exists, then the validation will fail by throwing an InvalidPluginExecutionException. To verify that the account number exists, we query CRM using the ICrmService.Fetch method with a FetchXML query. The following code demonstrate these changes:

public class AccountNumberValidator : IPlugin
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="context"></param>
    public void Execute(IPluginExecutionContext context)
    {
        var target = (DynamicEntity) context.InputParameters[ParameterName.Target];

        if (target.Properties.Contains("accountnumber"))
        {
            var accountNumber = target["accountnumber"].ToString();

            // Validates the account number format.
            var regex = new Regex("[A-Z]{2}-[0-9]{6}");
            if (!regex.IsMatch(accountNumber))
            {
                throw new InvalidPluginExecutionException("Invalid account number.");
            }

            // Validates the account number is unique.
            using (var service = context.CreateCrmService(true))
            {
                var query = string.Format(@"<fetch mapping='logical'>
                                                <entity name='account'>
                                                <attribute name='accountnumber' />
                                                <filter>
                                                <condition attribute='accountnumber'
                                                    operator='eq' value='{0}' />
                                                </filter>
                                                </entity>
                                            </fetch>",
                                            accountNumber);

            var results = service.Fetch(query);
            var xdocument = XDocument.Parse(results);
            var existingNumbers = from item in xdocument.Descendants("accountnumber")
            select item.Value;

            if (existingNumbers.Count() > 0)
                throw new InvalidPluginExecutionException("Account number already exist.");
            }
        }
    }
}

Now, we will create a unit test to verify that our plug-in detects duplicate account numbers.

[Test]
[ExpectedException(typeof(InvalidPluginExecutionException))]
public void ShoulRejectDuplicateAccountNumber()
{
    // Create necessary mocks for the plug-in.
    var mocks = new MockRepository();
    var context = mocks.DynamicMock<IPluginExecutionContext>();
    var service = mocks.DynamicMock<ICrmService>();

    // Creates a property bag for the plugin execution context mock.
    var target = new DynamicEntity();
    target.Properties["accountnumber"] = "AB-123456";
    var inputParameters = new PropertyBag();
    inputParameters.Properties[ParameterName.Target] = target;

    // Set expectations of mocks.
    Expect.Call(context.InputParameters).Return(inputParameters).Repeat.Any();
    Expect.Call(context.CreateCrmService(true)).Return(service);
    Expect.Call(service.Fetch(null)).IgnoreArguments()
                .Return(@"<resultset>
                            <result>
                                <accountnumber>AB-123456</accountnumber>
                            </result>
                        </resultset>");
    mocks.ReplayAll();

    // Test the plug-in using the context mock.
    IPlugin plugin = new AccountNumberValidator();
    plugin.Execute(context);

    // Verify all the mocks.
    mocks.VerifyAll();
}

In the test above, we are using Rhino Mocks to create a mock for the ICrmService. This object will be returned by the CreateCrmService method of the plug-in execution context. We are also recording that when ICrmService.Fetch method is called, it will return a XML file containing a duplicated account number. This will simulate the CRM behavior of detecting that an account number already exists, and we can assert that our plug-in will fail the validation by throwing an exception.

I hope this post helps you to unit test your CRM plug-ins. Although I demonstrated it using NUnit and Rhino Mocks, you can use any unit testing framework (NUnit, MbUnit, Visual Studio Tests, etc.) and any mock framework (Rhino Mocks, NMock, Typemocks, etc.).

Monday, June 15, 2009

Using Embedded Files for FetchXML Queries

FetchXML is a proprietary language that it is used in Microsoft Dynamics CRM. All examples that I've seen so far, always show the FetchXML query hard coded into the C# file. Instead of keeping the queries mixed with the source code, a bad practice IMHO, I prefer placing queries in separate XML files. These files can be embedded resources of the assembly. By placing them on a separate file, it isolates them from the code, making easier to locate, share and test them. In order to embed your query in the assembly, you will need to add an XML file with the query into your project. Make sure to change its build action to Embedded Resource. Then, use the following code to read the embedded XML file. The code below assumes that the file was placed in the subfolder Queries of the project. It refers to the embedded file by using the assembly name and the related path to the file. Notice that it uses "." instead of "\" to refer to the embedded file.

// Read the embedded fetch xml query file.
var assembly = Assembly.GetExecutingAssembly();
var stream = assembly.GetManifestResourceStream("MyAssembly.Queries.MyQuery.xml");

if (stream == null)
{
    throw new FileLoadException("Cannot load fetchXML embedded file");
}

// Gets the Fetch XML query string.
var reader = new StreamReader(stream);
string query = reader.ReadToEnd();

// Removing leading spaces to reduce the size of the xml request.
query = Regex.Replace(fetchXml, @"\s+", @" ");

// Fetches the results.
string results = crmService.Fetch(query);

The code above uses a static query. If you need to use a dynamic query, then the XML can contain the string format of the query, and you can use String.Format to pass the parameters needed to build your dynamic query.

Wednesday, May 20, 2009

Visual Studio 2010 and .NET 4 Beta 1

Visual Studio 2010 and .NET 4 Beta 1 is available today for the general public. Note that the new .NET version is 4 and not 4.0. You can download the beta from here.

Also, check out Jason Zander's post where he highlights the new functionalities, and Brad Adams post with .NET 4 poster.

I am currently preparing a virtual machine with Windows 7 RC 1 and VS 2010 for trying out the new features.