Maarten Balliauw {blog}

ASP.NET, ASP.NET MVC, Windows Azure, PHP, ...

NAVIGATION - SEARCH

Books I recently read...

A while ago, I was contacted by the people of Packt Publishing asking me to review two of their latest books, ASP.NET Data Presentation Controls Essentials (by Joydip Kanjilal) and LINQ Quickly (by N. Satheesh Kumar). Since both books stated something about LINQ on the back-cover, and me wanting to read more on that matter, I engaged into reviewing them.

ASP.NET Data Presentation Controls Essentials

image Being an ASP.NET developer, I'm not new to ASP.NET's data bound controls. Upon receiving the book, I immediately knew this was not going to be new stuff to me, a thought which proved right. Nevertheless, the book has a value!

The author starts with a birds-eye overview of all data bound controls in ASP.NET, allowing the reader to immediately know what's possible with these controls. In the next chapters, each control is covered with some examples. Luckily, the book did not contain "full" examples yet short, to-the-point code snippets delivering a practical approach to solving a specific data binding scenario.

This leads me to agreeing with the author that "this book is not for beginners". Some snippets contain small typo's, and because a full frame around these snippets is missing, someone new to C# and ASP.NET will have some problems creating their own examples based on the book. It's also not for professionals to learn much new things, but I think anyone familiar with a C# background wanting to start data bound ASP.NET development can benefit from this no-nonsense quickstart book.

For me, this book will find a place on my book shelf along with other reference books, as it covers all data binding scenario's from ASP.NET 1.1 over ASP.NET 2.0 up to some snippets of data binding to LINQ data sources.

LINQ Quickly

image Since the release of the Microsoft .NET framework 3.5 a few months ago, I've been playing around with LINQ (Language Integrated Query) a couple of times. It is a uniform method of accessing any type of data (Collections, XML, database, ...) in a "natural" way.

The book covers all concepts of LINQ. It starts with an overview of all language elements that have been added to the .NET framework in order to enable the use of LINQ, such as anonymous types, object/collection initializers, expressions, partial methods, ... The next chapters all cover a LINQ implementation such as LINQ to Objects, LINQ to SQL, LINQ to Entities, LINQ to XML, LINQ to DataSets, ... The last chapter gives an overview of all LINQ methods and their use with a short code example that immediately clarifies the purpose of each method.

I found the LINQ to Entities chapter quite interesting, as it clearly explains how to create your class diagram using the right decorators for generating a database schema. Another useful thing are the appendices near the end of the book, covering LINQ to "anything" (there's an example on LINQ to Outlook Contacts).

To be honest, I'm quite enthousiast about this book. If you are a .NET developer and looking for a "one-night read" to-the-point book about LINQ and all related matter, this book is your friend!

ASP.NET Session State Partitioning using State Server Load Balancing

It seems like amount of posts on ASP.NET's Session State keeps growing. Here's the list:

Yesterday's post on Session State Partitioning used a round-robin method for partitioning session state over different state server machines. The solution I presented actually works, but can still lead to performance bottlenecks.

Let's say you have a web farm running multiple applications, all using the same pool of state server machines. When having multiple sessions in each application, the situation where one state server handles much more sessions than another state server could occur. For that reason, ASP.NET supports real load balancing of all session state servers.

Download example

Want an instant example? Download it here: SessionPartitioning2.zip (4.16 kb)
Want to know what's behind all this? Please, continue reading.

What we want to achieve...

Here's a scenario: We have different applications running on a web farm. These applications all share the same pool of session state servers. Whenever a session is started, we want to store it on the least-busy state server.

1. Performance counters

To fetch information on the current amount of sessions a state server is storing, we'll use the performance counters ASP.NET state server provides. Here's a code snippet:

[code:c#]

if (PerformanceCounterCategory.CounterExists("State Server Sessions Active", "ASP.NET", "STATESERVER1")) {
    PerformanceCounter pc = new PerformanceCounter("ASP.NET", "State Server Sessions Active", "", "STATESERVER1");
    float currentLoad = pc.NextValue();
}

[/code]

2. Creating a custom session id

Somehow, ASP.NET will have to know on which server a specific session is stored. To do this, let's say we make the first character of the session id the state server id from the following IList:

[code:c#]

IList<StateServer> stateServers = new List<StateServer>();

// Id 0, example session id would be 0ywbtzez3eqxut45ukyzq3qp
stateServers.Add(new StateServer("tcpip=10.0.0.1:42424", "sessionserver1"));

// Id 1, example session id would be 1ywbtzez3eqxut45ukyzq3qp
stateServers.Add(new StateServer("tcpip=10.0.0.2:42424", "sessionserver2"));

[/code]

Next thing we'll have to do is storing these list id's in the session id. For that, we will implement a custom System.Web.SessionState.SessionIDManager class. This class simply creates a regular session id, locates the least-busy state server instance and assign the session to that machine:

[code:c#]

using System;
using System.Diagnostics;


public class SessionIdManager : System.Web.SessionState.SessionIDManager
{
    public override string CreateSessionID(System.Web.HttpContext context)
    {
        // Generate a "regular" session id
        string sessionId = base.CreateSessionID(context);

        // Find the least busy state server
        StateServer leastBusyServer = null;
        float leastBusyValue = 0;
        foreach (StateServer stateServer in StateServers.List)
        {
            // Fetch first state server
            if (leastBusyServer == null) leastBusyServer = stateServer;

            // Fetch server's performance counter
            if (PerformanceCounterCategory.CounterExists("State Server Sessions Active", "ASP.NET", stateServer.ServerName))
            {
                PerformanceCounter pc = new PerformanceCounter("ASP.NET", "State Server Sessions Active", "", stateServer.ServerName);
                if (pc.NextValue() < leastBusyValue || leastBusyValue == 0)
                {
                    leastBusyServer = stateServer;
                    leastBusyValue = pc.NextValue();
                }
            }
        }

        // Modify session id to contain the server's id
        // We will change the first character in the string to be the server's id in the
        // state server list. Notice that this is only for demonstration purposes! (not secure!)
        sessionId = StateServers.List.IndexOf(leastBusyServer).ToString() + sessionId.Substring(1);

        // Return
        return sessionId;
    }
}

[/code]

The class we created will have to be registered in web.config. Here's how:

[code:c#]

<configuration>
  <system.web>
    <!-- ... -->
    <sessionState mode="StateServer"
                partitionResolverType="PartitionResolver"
                sessionIDManagerType="SessionIdManager" />
    <!-- ... -->
  </system.web>
</configuration>

[/code]

You notice our custom SessionIdManager class is now registered to be the sessionIDManager. The PartitionResolver I blogged about is also present in a modified version.

3. Using the correct state server for a specific session id

In the previous code listing, we assigned a session to a specific server. Now for ASP.NET to read session state from the correct server, we still have to use the PartitionResolver class:

[code:c#]

using System;


public class PartitionResolver : System.Web.IPartitionResolver
{

    #region IPartitionResolver Members

    public void Initialize()
    {
        // No need for this!
    }

    public string ResolvePartition(object key)
    {
        // Accept incoming session identifier
        // which looks similar like "2ywbtzez3eqxut45ukyzq3qp"
        string sessionId = key as string;

        // Since we defined the first character in sessionId to contain the
        // state server's list id, strip it off!
        int stateServerId = int.Parse(sessionId.Substring(0, 1));

        // Return the server's connection string
        return StateServers.List[stateServerId].ConnectionString;
    }

    #endregion

}

[/code]

kick it on DotNetKicks.com 

ASP.NET Session State Partitioning

After my previous blog post on ASP.NET Session State, someone asked me if I knew anything about ASP.NET Session State Partitioning. Since this is a little known feature of ASP.NET, here's a little background and a short how-to.

When scaling out an ASP.NET application's session state to a dedicated session server (SQL server or the ASP.NET state server), you might encounter a new problem: what if this dedicated session server can't cope with a large amount of sessions? One option might be to create a SQL server cluster for storing session state. A cheaper way is to implement a custom partitioning algorithm which redirects session X to state server A and session Y to state server B. In short, partitioning provides a means to divide session information on multiple session state servers, which all handle "their" part of the total amount of sessions.

Download example 

Want an instant example? Download it here: SessionPartitioning.zip (2.70 kb)
 Want to know what's behind all this? Please, continue reading.

1. Set up ASP.NET session mode

Follow all steps in my previous blog post to set up the ASP.NET state service / SQL state server database and the necessary web.config setup. We'll customise this afterwards.

2.   Create your own session state partitioning class

The "magic" of this el-cheapo solution to multiple session servers will be your own session state partitioning class. Here's an example:

[code:c#]

using System;

public class PartitionResolver : System.Web.IPartitionResolver
{

    #region Private members

    private String[] partitions;

    #endregion

    #region IPartitionResolver Members

    public void Initialize()
    {
        // Create an array containing
        // all partition connection strings
        //
        // Note that this could also be an array
        // of SQL server connection strings!
        partitions = new String[] {      
            "tcpip=10.0.0.1:42424",   
            "tcpip=10.0.0.2:42424",       
            "tcpip=10.0.0.3:42424"
        };
    }

    public string ResolvePartition(object key)
    {
        // Accept incoming session identifier
        // which looks similar like "2ywbtzez3eqxut45ukyzq3qp"
        string sessionId = key as string;

        // Create your own manner to divide session id's
        // across available partitions or simply use this one!
        int partitionID = Math.Abs(sessionId.GetHashCode()) % partitions.Length;
        return partitions[partitionID];
    }

    #endregion
}

[/code]

Basically, you just have to implement the interface System.Web.IPartitionResolver, which is the contract ASP.NET uses to determine the session state server's connection string. The ResolvePartition method is called with the current session id in it, and allows you to return the connection string that should be used for that specific session id.

3. Update your web.config

Most probably, you'll have a web.config which looks like this:

[code:xml]

<configuration>
  <system.web>
    <!-- ... -->
    <sessionState
        mode="StateServer"
        stateConnectionString="tcpip=your_server_ip:42424" />
    <!-- ... -->
  </system.web>
</configuration>

[/code]

In order for ASP.NET to use our custom class, modify web.config into:

[code:xml]

<configuration>
  <system.web>
    <!-- ... -->
    <sessionState
        mode="StateServer"
        partitionResolverType="PartitionResolver" />
    <!-- ... -->
  </system.web>
</configuration>

[/code]

You may have noticed that the stateConnectionString attribute was replaced by a partitionResolverType attribute. From now on, ASP.NET will use the class specified in the partitionResolverType attribute for distributing sessions across state servers.

UPDATE 2008-01-24: Also check out my blog post on Session State Partitioning using load balancing!

kick it on DotNetKicks.com

LINQ for PHP (Language Integrated Query for PHP)

Perhaps you have already heard of C# 3.5's "LINQ" component. LINQ, or Language Integrated Query, is a component inside the .NET framework which enables you to perform queries on a variety of data sources like arrays, XML, SQL server, ... These queries are defined using a syntax which is very similar to SQL.

There is a problem with LINQ though... If you start using this, you don't want to access data sources differently anymore. Since I'm also a PHP developer, I thought of creating a similar concept for PHP. So here's the result of a few days coding:

PHPLinq - LINQ for PHP - Language Integrated Query

A basic example

Let's say we have an array of strings and want to select only the strings whose length is < 5. The PHPLinq way of achieving this would be the following:

[code:c#]

// Create data source
$names = array("John", "Peter", "Joe", "Patrick", "Donald", "Eric");

$result = from('$name')->in($names)
            ->where('$name => strlen($name) < 5')
            ->select('$name');

[/code]

Feels familiar to SQL? Yes indeed! No more writing a loop over this array, checking the string's length, and adding it to a temporary variable.

You may have noticed something strange... What's that $name => strlen($name) < 5 doing? This piece of code is compiled to an anonymous function or Lambda expression under the covers. This function accepts a parameter $name, and returns a boolean value based on the expression strlen($name) < 5.

An advanced example

There are lots of other examples available in the PHPLinq download, but here's an advanced one... Let's say we have an array of Employee objects. This array should be sorted by Employee name, then Employee age. We want only Employees whose name has a length of 4 characters. Next thing: we do not want an Employee instance in our result. Instead, the returning array should contain objects containing an e-mail address and a domain name.

First of all, let's define our data source:

[code:c#]

class Employee {
    public $Name;
    public $Email;
    public $Age;

    public function __construct($name, $email, $age) {
        $this->Name     = $name;
        $this->Email     = $email;
        $this->Age        = $age;
    }
}

$employees = array(
    new Employee('Maarten', 'maarten@example.com', 24),
    new Employee('Paul', 'paul@example.com', 30),
    new Employee('Bill', 'bill.a@example.com', 29),
    new Employee('Bill', 'bill.g@example.com', 28),
    new Employee('Xavier', 'xavier@example.com', 40)
);

[/code]

Now for the PHPLinq query:

[code:c#]

$result = from('$employee')->in($employees)
            ->where('$employee => strlen($employee->Name) == 4')
            ->orderBy('$employee => $employee->Name')
            ->thenByDescending('$employee => $employee->Age')
            ->select('new {
                    "EmailAddress" => $employee->Email,
                    "Domain" => substr($employee->Email, strpos($employee->Email, "@") + 1)
                  }');

[/code]

Again, you may have noticed something strange... What's this new { } thing doing? Actually, this is converted to an anonymous type under the covers. new { "name" => "test" } is evaluated to an object containing the property "name" with a value of "test".

This all sounds intuitive, interesting and very handy? Indeed! Now make sure you download a copy of PHPLinq today, try it, and provide the necessary feedback / feature requests on the CodePlex site.

Preview Word files (docx) in HTML using ASP.NET, OpenXML and LINQ to XML

Since an image (or even an example) tells more than any text will ever do, here's what I've created in the past few evening hours:

image

Live examples:

Want the source code? Download it here: WordVisualizer.zip (357.01 kb)

Want to know how?

If you want to know how I did this, let me first tell you why I created this. After searching Google for something similar, I found a Sharepoint blogger who did the same using a Sharepoint XSL transformation document called DocX2Html.xsl. Great, but this document can not be distributed without a Sharepoint license. The only option for me was to do something similar myself.

ASP.NET handlers

The main idea of this project was to be able to type in a URL ending in ".docx", which would then render a preview of the underlying Word document. Luckily, ASP.NET provides a system of creating HttpHandlers. A HttpHandler is the class instance which is called by the .NET runtime to process an incoming request for a specific extension. So let's trick ASP.NET into believing ".docx" is an extension which should be handled by a custom class...

Creating a custom handler

A custom handler can be created quite easily. Just create a new class, and make it implement the IHttpHandler interface:

[code:c#]

/// <summary>
/// Word document HTTP handler
/// </summary>

public class WordDocumentHandler : IHttpHandler
{
    #region IHttpHandler Members

    /// <summary>
    /// Is the handler reusable?
    /// </summary>

    public bool IsReusable
    {
        get { return true; }
    }

    /// <summary>
    /// Process request
    /// </summary>
    /// <param name="context">Current http context</param>

     public void ProcessRequest(HttpContext context)
    {
        // Todo...

        context.Response.Write("Hello world!");
    }

    #endregion
}

[/code]

Registering a custom handler

For ASP.NET to recognise our newly created handler, we must register it in Web.config:

image

Now if you are using IIS6, you should also register this extension to be handled by the .NET runtime:

image

In the application configuration, add the extension ".docx" and make it point to the following executable: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll

This should be it. Fire up your browser, browse to your web site and type anything.docx. You should see "Hello world!" appearing in a nice, white page.

OpenXML

As you may already know, Word 2007 files are OpenXML packages containg WordprocessingML markup. A .docx file can be opened using the System.IO.Packaging.Package class (which is available after adding a project reference to WindowsBase.dll).

The Package class is created for accessing any OpenXML package. This includes all Office 2007 file formats, but also custom OpenXML formats which you can implement for yourself. Unfortunately, if you want to use Package to access an Office 2007 file, you'll have to implement a lot of utility functions to get the right parts from the OpenXML container.

Luckily, Microsoft released an OpenXML SDK (CTP), which I also used in order to create this Word preview handler.

LINQ to XML

As you know, the latest .NET 3.5 release brought us something new & extremely handy: LINQ (Language Integrated Query). On Doug's blog, I read about Eric White's attempts to use LINQ to XML on OpenXML.

LINQ to OpenXML

For implementing my handler, I basically used similar code to Eric's to run query's on a Word document's contents. Here's an example which fetches all paragraphs in a Word document:

[code:c#]

using (WordprocessingDocument document = WordprocessingDocument.Open("test.docx", false))
{
    // Register namespace

    XNamespace w = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";

    // Element shortcuts

    XName w_r = w + "r";
    XName w_ins = w + "ins";
    XName w_hyperlink = w + "hyperlink";

    // Load document's MainDocumentPart (document.xml) in XDocument

    XDocument xDoc = XDocument.Load(
        XmlReader.Create(
            new StreamReader(document.MainDocumentPart.GetStream())
        )
    );

    // Fetch paragraphs

    var paragraphs = from l_paragraph in xDoc
                    .Root
                    .Element(w + "body")
                    .Descendants(w + "p")
         select new
         {
             TextRuns = l_paragraph.Elements().Where(z => z.Name == w_r || z.Name == w_ins || z.Name == w_hyperlink)
         };

    // Write paragraphs

    foreach (var paragraph in paragraphs)
    {
        // Fetch runs

        var runs = from l_run in paragraph.Runs
                   select new
                   {
                       Text = l_run.Descendants(w + "t").StringConcatenate(element => (string)element)
                   };

        // Write runs

        foreach (var run in runs)
        {
            // Use run.Text to fetch a text string

            Console.Write(run.Text);
        }
    }
}

[/code]

Now if you run this code, you will notice a compilation error... This is due to the fact that I used an extension method StringConcatenate.

Extension methods

In the above example, I used an extension method named StringConcatenate. An extension method is, as the name implies, an "extension" to a known class. In the following example, find the extension for all IEnumerable<T> instances:

[code:c#]

public static class IEnumerableExtensions
{
    /// <summary>
    /// Concatenate strings
    /// </summary>
    /// <typeparam name="T">Type</typeparam>
    /// <param name="source">Source</param>
    /// <param name="func">Function delegate</param>
    /// <returns>Concatenated string</returns>

    public static string StringConcatenate<T>(this IEnumerable<T> source, Func<T, string> func)
    {
        StringBuilder sb = new StringBuilder();
        foreach (T item in source)
            sb.Append(func(item));
        return sb.ToString();
    }
}

[/code]

Lambda expressions

Another thing you may have noticed in my example code, is a lambda expression:

[code:c#]

z => z.Name == w_r || z.Name == w_ins || z.Name == w_hyperlink.

[/code]

A lambda expression is actually an anonymous method, which is called by the StringConcatenate extension method. Lambda expressions always accept a parameter, and return true/false. In this case, z is instantiated as an XNode, returning true/false depending on its Name property.

Wrapping things up...

If you read this whole blog post, you may have noticed that I extensively used C# 3.5's new language features. I combined these with OpenXML and ASP.NET to create a useful Word document preview handler. If you want the full source code, download it here: WordVisualizer.zip (357.01 kb).

kick it on DotNetKicks.com