Maarten Balliauw {blog}

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

NAVIGATION - SEARCH

Introducing RealDolmenBlogs.com

RealDolmenBlogs.com Here’s something I would like to share with you. A few months ago, our company (RealDolmen) started a new website, RealDolmenBlogs.com. This site syndicates content from employee blogs, people with lots of experience in their range of topics. These guys have lots of knowledge to share, but sometimes their blog does not have a lot of attention from, well, you. Since we would really love to share employee knowledge, RealDolmenBlogs.com was born.

The following topics are covered:

  • .NET
  • Application Lifecycle Management
  • Architecture
  • ASP.NET
  • Biztalk
  • PHP
  • Sharepoint
  • Silverlight
  • Visual Studio

Make sure to subscribe to the syndicated RSS feed and have quality content delivered to your RSS reader.

The technical side

Since I do not like to do blog posts on topic that do not have a technical touch, considered that the first few lines of text of this post are pure marketing in a sense, here’s the technical bit.

RealDolmenBlogs.com is built on Windows Azure and SQL Azure. As a company we believe there is value in cloud computing, in this case we chose for cloud computing due to the fact that the setup costs for the website were very small (pay-per-use) and that we can easily scale-up the website if needed.

The software behind the site is a customized version of BlogEngine.NET. It has been extended with a syndication feature, pulling content from employee blogs with a little help of the Argotic syndication framework. Running BlogEngine.NET on Windows Azure is not that hard, especially when you are using SQL Azure as well: the only thing to modify is the connection string to your database and you are done. Well… that is if you don’t care about images and attachments. We had to do some modifications to how BlogEngine.NET handles file uploads and made sure everything is now stored safe and sound in Windows Azure blob storage.

That being said: enjoy the content that my colleagues are sharing, posts are definitely worth a read!

Running PHP in the Cloud slides and sample code

Just got back from London where I did a fun talk on PHP and Windows Azure yesterday evening. It was the first time I did a presentation after three beers, but I think it went allright. As promised, here's the slide deck and sample code (ImageCloud.rar (5.00 mb)).

Abstract: "This session covers the basics of Microsoft’s Windows Azure cloud platform. Learn how you can develop and deploy a PHP application in Windows Azure, using the tools and libraries Microsoft provides. Creating a photo upload application, the different aspects of the Windows Azure platform are leveraged for creating a performant and scalable PHP application."

Thanks for joining the conference and my session! Also, Robert Castelo, your talk on Drupal and its community was interesting. Did not know the active developer base and security teams were that big.

Sharpy - an ASP.NET MVC view engine based on Smarty

Sharpy - ASP.NET MVC View Engine based on SmartyAre you also one of those ASP.NET MVC developers who prefer a different view engine than the default Webforms view engine available? You tried Spark, NHaml, …? If you are familiar with the PHP world as well, chances are you know Smarty, a great engine for creating views that can easily be read and understood by both developers and designers. And here’s the good news: Sharpy provides the same syntax for ASP.NET MVC!

If you want more details on Sharpy, visit Jaco Pretorius’ blog:

kick it on DotNetKicks.com

A simple example…

Here’s a simple example:

[code:c#]

{master file='~/Views/Shared/Master.sharpy' title='Hello World sample'}

<h1>Blog entries</h1>

{foreach from=$Model item="entry"}
    <tr>
        <td>{$entry.Name|escape}</td>       
        <td align="right">{$entry.Date|date_format:"dd/MMM/yyyy"}</td>       
    </tr>
    <tr>
        <td colspan="2" bgcolor="#dedede">{$entry.Body|escape}</td>
    </tr>
{foreachelse}
    <tr>
        <td colspan="2">No records</td>
    </tr>
{/foreach}

[/code]

The above example first specifies the master page to use. Next, a foreach-loop is executed for each blog post (aliased “entry”) in the $Model. Printing the entry’s body is done using {$entry.Body|escape}. Note the pipe “|” and the word escape after it. These are variable modifiers that can be used to escape content, format dates, …

Extensibility

Sharpy is all about extensibility: every function in a view is actually a plugin of a specific type (there are four types, IInlineFunction, IBlockFunction, IExpressionFunction and IVariableModifier). These plugins are all exposed through MEF. This means that Sharpy will always use any of your custom functions that are exposed through MEF. For example, here’s a custom function named “content”:

[code:c#]

[Export(typeof(IInlineFunction))]
public class Content : IInlineFunction
{
    public string Name
    {
        get { return "content"; }
    }

    public string Evaluate(IDictionary<string, object> attributes, IFunctionEvaluator evaluator)
    {
        // Fetch attributes
        var file = attributes.GetRequiredAttribute<string>("file");

        // Write output
        return evaluator.EvaluateUrl(file);
    }
}

[/code]

Here’s how to use it:

[code:c#]

{content file='~/Content/SomeFile.txt'}

[/code]

Sharpy uses MEF to allow developers to implement their own functions and modifiers.  All the built-in functions are also built using this exact same framework – the same functionality is available to both internal and external functions.

Extensibility is one of the strongest features in Sharpy.  This should allow us to leverage any functionality available in a normal ASP.NET view while maintaining simple views and straightforward markup.

Give it a spin!

Do give Sharpy a spin, you will learn to love it.

Jump in! camp - Call for participants

Jump In! Camp I just got the following invitation from Microsoft, and would like to encourage  you to participate as well if you are interested in bot PHP and the Microsoft worlds.

Jump In! and be a part of it!

Open source programming and Microsoft: two incompatible worlds? Microsoft is partnering with renowned actors of the open-source community to organise the Jump In! Developers' Camp in an effort to combat this misperception. Twenty-five knowledge-hungry open source application developers from all over Europe will be invited to spend four unforgettable days of dialogue, networking and workshops at the beautiful Panorama Resort & Spa Feusisberg in Switzerland.

The Jump In! Developers' Camp is designed primarily for open-source application developers who are interested in increasing their skills in a range of specific areas. Here they will be able to experiment with ways of combining open-source technologies with Microsoft products to optimize applications. But don’t worry: no one is out to ‘convert’ anybody! The aim instead is to promote interoperability, problem-solving and enhance programming skills. Software experts will be on hand to provide tips and advice, and a range of workshops will be held on topics including Azure, IIS, Silverlight and more in combination with open-source applications. Plenty of time for actual coding will be available.

Potential participants are invited to file an application at www.jumpincamp.com, outlining their profile. The 25 developers who are creating the most “buzz” for themselves and their programming abilities will then be selected. Attendees of the JumpIn! Developers' Camp will then record their impressions and experiences in a live blog for their community of ‘followers’. The Camp will be held between 6 - 9 April 2010.

Register now and apply for taking part on www.jumpincamp.com.

Using Windows Azure Drive (aka X-Drive)

Windows Azure X Drive With today’s release of the Windows Azure Tools and SDK version 1.1, also the Windows Azure Drive feature has been released. Announced at last year’s PDC as X-Drive, which has nothing to do with a well-known German car manufacturer, this new feature enables a Windows Azure application to use existing NTFS APIs to access a durable drive. This allows the Windows Azure application to mount a page blob as a drive letter, such as X:, and enables easily migration of existing NTFS applications to the cloud.

This blog post will describe the necessary steps to create and/or mount a virtual hard disk on a Windows Azure role instance.

kick it on DotNetKicks.com

Using Windows Azure Drive

In a new or existing cloud service, make sure you have a LocalStorage definition in ServiceDefinition.csdef. This local storage, defined with the name InstanceDriveCache below, will be used by the Windows Azure Drive API to cache virtual hard disks on the virtual machine that is running, enabling faster access times. Here’s the ServiceDefinition.csdef for my project:

[code:c#]

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="MyCloudService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WorkerRole name="MyWorkerRole" enableNativeCodeExecution="true">
    <LocalResources>
      <LocalStorage name="InstanceDriveCache"
                    cleanOnRoleRecycle="false"
                    sizeInMB="300" />
    </LocalResources>
    <ConfigurationSettings>
      <!-- … -->
   </ConfigurationSettings>
  </WorkerRole>
</ServiceDefinition>

[/code]

Next, in code, fire up a CloudStorageAccount, I’m using development storage settings here:

[code:c#]

CloudStorageAccount storageAccount = CloudStorageAccount.DevelopmentStorageAccount;

[/code]

After that, the Windows Azure Drive environment has to be initialized. Remember the LocalStorage definition we made earlier? This is where it comes into play:

[code:c#]

LocalResource localCache = RoleEnvironment.GetLocalResource("InstanceDriveCache");
CloudDrive.InitializeCache(localCache.RootPath, localCache.MaximumSizeInMegabytes);

[/code]

Just to be sure, let’s create a blob storage container with any desired name, for instance “drives”:

[code:c#]

CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
blobClient.GetContainerReference("drives").CreateIfNotExist();

[/code]

Ok, now we got that, it’s time to get a reference to a Windows Azure Drive. Here’s how:

[code:c#]

CloudDrive myCloudDrive = storageAccount.CreateCloudDrive(
    blobClient
        .GetContainerReference("drives")
        .GetPageBlobReference("mysupercooldrive.vhd")
        .Uri.ToString()
);

[/code]

Our cloud drive will be stored in a page blob on the “drives” blob container, named “mysupercooldrive.vhd”. Note that when using development settings, the page blob will not be created on development storage. Instead, files will be located at C:\Users\<your.user.name>\AppData\Local\dftmp\wadd\devstoreaccount1.

Next up: making sure our virtual hard disk exists.  Note that this should only be done once in a virtual disk’s lifetime. Let’s create a giant virtual disk of 64 MB:

[code:c#]

try
{
    myCloudDrive.Create(64);
}
catch (CloudDriveException ex)
{
    // handle exception here
    // exception is also thrown if all is well but the drive already exists
}

[/code]

Great, our disk is created. Now let’s mount it, i.e. assign a drive letter to it. The drive letter can not be chosen, instead it is returned by the Mount() method. The 25 is the cache size that will be used on the virtual machine instance. The DriveMountOptions can be None, Force and FixFileSystemErrors.

[code:c#]

string driveLetter = myCloudDrive.Mount(25, DriveMountOptions.None);

[/code]

Great! Do whatever you like with your disk! For example, create some files:

[code:c#]

for (int i = 0; i < 1000; i++)
{
    System.IO.File.WriteAllText(driveLetter + "\\" + i.ToString() + ".txt", "Test");
}

[/code]

One thing left when the role instance is being shut down: unmounting the disk and makign sure all contents are on blob storage again:

[code:c#]

myCloudDrive.Unmount();

[/code]

Now, just for fun: you can also create a snapshot from a Windows Azure Drive by calling the Snapshot() method on it. A new Uri with the snapshot location will be returned.

Full code sample

The code sample described above looks like this when not going trough each line of code separately:

[code:c#]

public override void Run()

    CloudStorageAccount storageAccount = CloudStorageAccount.DevelopmentStorageAccount;

    LocalResource localCache = RoleEnvironment.GetLocalResource("InstanceDriveCache");
    CloudDrive.InitializeCache(localCache.RootPath, localCache.MaximumSizeInMegabytes);

    // Just checking: make sure the container exists
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
    blobClient.GetContainerReference("drives").CreateIfNotExist();

    // Create cloud drive
    CloudDrive myCloudDrive = storageAccount.CreateCloudDrive(
        blobClient
        .GetContainerReference("drives")
        .GetPageBlobReference("mysupercooldrive.vhd")
        .Uri.ToString()
    );

    try
    {
        myCloudDrive.Create(64);
    }
    catch (CloudDriveException ex)
    {
        // handle exception here
        // exception is also thrown if all is well but the drive already exists
    }

    string driveLetter = myCloudDrive.Mount(25, DriveMountOptions.Force);

    for (int i = 0; i < 1000; i++)
    {
        System.IO.File.WriteAllText(driveLetter + "\\" + i.ToString() + ".txt", "Test");
    }

    myCloudDrive.Unmount();
}

[/code]

Enjoy!

kick it on DotNetKicks.com

Just Another Wordpress Weblog, But More Cloudy

4322759659_6cab114506_b Slides of my talk at the PHPBenelux conference last weekend are online. Bit of a pity my live demo went wrong due to my www.azure.com trial account going into read-only mode while doing the demo.

Abstract: "While working together with Microsoft on the Windows Azure SDK for PHP, we found that we needed an popular example application hosted on Microsoft’s Windows Azure. Wordpress was an obvious choice, but not an obvious task. Learn more about Windows Azure, the PHP SDK that we developed, SQL Azure and about the problems we faced porting an existing PHP application to Windows Azure."

Thanks for joining the conference and my session! And thanks to the PHPBenelux crew for organizing their first conference ever, it rocked!