Maarten Balliauw {blog}

Web development, NuGet, Microsoft Azure, PHP, ...

NAVIGATION - SEARCH

ASP.NET MVC and jQuery Mobile

jQuery MobileWith the release of Windows Phone 7 last year, I’m really interested in mobile applications. Why? Well, developing for Windows Phone 7 did not require me to learn new things. I can use my current skill set and build cool apps for that platform. But what about the other platforms? If you look at all platforms from a web developer perspective, there’s one library that also allows you to use your existing skill set: jQuery Mobile.

Know HTML? Know jQuery? Know *any* web development language like PHP, RoR or ASP.NET (MVC)? Go ahead and build great looking mobile web apps!

I’ll give you a very short tutorial, just enough to sparkle some interest. After that, it’s up to you.

Getting jQuery Mobile running in ASP.NET MVC

This one is easy. Start a new project and strip out anything you don’t need. After that, modify your master page to something like this:

1 <%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %> 2 3 <!DOCTYPE html> 4 <html> 5 <head runat="server"> 6 <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title> 7 <link href="../../Content/Site.css" rel="stylesheet" type="text/css" /> 8 9 <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a2/jquery.mobile-1.0a2.min.css" /> 10 <script src="http://code.jquery.com/jquery-1.4.4.min.js"></script> 11 <script src="http://code.jquery.com/mobile/1.0a2/jquery.mobile-1.0a2.min.js"></script> 12 </head> 13 14 <body> 15 <asp:ContentPlaceHolder ID="MainContent" runat="server" /> 16 </body> 17 </html> 18

That’s it: you download all resources from jQuery’s CDN. Optionally, you can also download and host jQuery Mobile on your own server.

Creating a first page

Pages have their own specifics. If you look at the docs, a page typically consists of a div element with a HTML5 data attribute “data-role” “page”. These data attributes are used for anything you would like to accomplish, which means your PC or device needs a HTML5 compatible browser to render jQuery Mobile content. Here’s a simple page (using ASP.NET MVC):

1 <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<RealDolmenMobile.Web.Models.ListPostsModel>" %> 2 3 <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 4 Page title 5 </asp:Content> 6 7 <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 8 <div data-role="page"> 9 10 <div data-role="header"> 11 <h1>Title here</h1> 12 </div> 13 14 <div data-role="content"> 15 <p>Contents here</p> 16 </div> 17 18 <div data-role="footer"> 19 <h4>Footer here</h4> 20 </div> 21 </div> 22 </asp:Content>

Building a RSS reader

I’ve been working on a simple sample which formats our RealDolmen blogs into jQuery Mobile UI. Using Argotic as the RSS back-end, this was quite easy to do. First of all, here’s a HomeController that creates a list of posts in a view model. MVC like you’re used to work with:

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 using Argotic.Syndication; 7 using RealDolmenMobile.Web.Models; 8 using System.Web.Caching; 9 10 namespace RealDolmenMobile.Web.Controllers 11 { 12 [HandleError] 13 public class HomeController : Controller 14 { 15 private static readonly Uri Feed = new Uri("http://microsoft.realdolmenblogs.com/Syndication.axd"); 16 17 public ActionResult Index() 18 { 19 // Create model 20 var model = new ListPostsModel(); 21 22 GenericSyndicationFeed feed = GenericSyndicationFeed.Create(Feed); 23 foreach (GenericSyndicationItem item in feed.Items) 24 { 25 model.Posts.Add(new PostModel 26 { 27 Title = item.Title, 28 Body = item.Summary, 29 PublishedOn = item.PublishedOn 30 }); 31 } 32 33 return View(model); 34 } 35 }

Next, we need to render this. Again, pure HTML goodness that you’re used working with:

1 <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<RealDolmenMobile.Web.Models.ListPostsModel>" %> 2 3 <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 4 RealDolmen Blogs 5 </asp:Content> 6 7 <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 8 <div data-role="page"> 9 10 <div data-role="header"> 11 <h1>RealDolmen Blogs</h1> 12 </div> 13 14 <div data-role="content"> 15 <ul data-role="listview"> 16 <li data-role="list-divider">Posts by employees<span class="ui-li-count"><%:Model.Posts.Count()%></span></li> 17 <% 18 foreach (var post in Model.Posts) 19 { 20 %> 21 <li> 22 <h3><%:Html.ActionLink(post.Title, "Post", new { title = post.Title })%></h3> 23 <p class="ui-li-aside">Published: <%:post.PublishedOn.ToString()%></p> 24 </li> 25 <% 26 } 27 %> 28 </ul> 29 </div> 30 31 <div data-role="footer"> 32 <h4>&nbsp;</h4> 33 </div> 34 </div> 35 </asp:Content>

The result? Not very stunning when looked at with IE8… But fire up Chrome or any other HTML5 capable browser, and here’s what you get:

RealDolmen Blogs Mobile

I’ve asked some people to check http://rd.cloudapp.net (may be offline by the time you read this), and I’ve received confirmation that it looks good on iSomething-devices, a Nokia and some Opera Mobile versions. Nice!

Goodies

The above example may not be that spectacular. The framework does hold some spectacular things! Think dialogs, forms, gestures, animations and a full-blown navigation framework that replaces any form or hyperlink with an AJAX call that is executed in the back-end, displays a nice “loading” screen and automatically generates a “back” button for you.

More examples? Check the manual itself over at http://jquerymobile.com/demos/1.0a2/docs/: this has been built using jQuery Mobile and looks nice!

Conclusion

It’s great! Really, I can just go ahead and build cool mobile web sites / web apps. Unfortunately, the WIndows-market of devices has bad support (due to a lack of HTML 5 support on their devices). This should get fixed in a coming upgrade, but untill then you will not have any luck running these apps on Windows Phone 7… For a complete list of compatible browsers and platforms, check the compatibility matrix.

For those interested, I’ve uploaded my small test app here: RealDolmenMobile.zip (420.38 kb) (note that I've built this as a Windows Azure solution)

Tools for the lazy: Templify and NuGet

In this blog post, I will cover two interesting tools that, when combined, can bring great value and speed at the beginning of any new software project that has to meet standards that are to be re-used for every project. The tools? Templify and NuGet.

You know the drill. Starting off with a new project usually consists of boring, repetitive tasks, often enforced by (good!) practices defined by the company you work for (or by yourself for that company). To give you an example of a project I’ve recently done:

  1. Create a new ASP.NET MVC application in Visual Studio
  2. Add 2 new projects: <project>.ViewModels and <project>.Controllers
  3. Do some juggling by moving classes into the right project and setting up the correct references between these projects

Maybe you are planning to use jQuery UI?

  1. Add the required JavaScript and CSS files to the project.

Oh right and what was that class you needed to work with MEF inside ASP.NET MVC? Let’s add that one as well:

  • Add the class for that
  • Add a reference to System.ComponentModel.Composition to the project

Admit it: these tasks are boring, time consuming and boring. Oh and time consuming. And boring. What if there were tools to automate a lot of this? And when I say a lot, I mean a LOT! Meet Templify and NuGet.

Introduction to Templify and NuGet

Well, let me leave this part to others. Let’s just do the following as an introduction: Templify is a tool that automates solution setup for Visual Studio in a super simple manner. It does not give you a lot of options, but that’s OK. Too much options are always bad. Want to read more on Templify? Check Howard van Rooijen’s introductory post.

NuGet (the package manager formerly known as NuPack) is a package manager for Visual Studio. It’s simple and powerful. Check Scott Hanselman’s excellent introduction post on this.

Scenario

Let’s go with the scenario I started my blog post with. You want to automate the boring tasks that are required at every project start. Here’s a simple one, usually it’s even more.

  1. Create a new ASP.NET MVC application in Visual Studio
  2. Add 2 new projects: <project>.ViewModels and <project>.Controllers
  3. Do some juggling by moving classes into the right project and setting up the correct references between these projects

Oh right and what was that class you needed to work with MEF inside ASP.NET MVC? Let’s add that one as well:

  • Add the class for that
  • Add a reference to System.ComponentModel.Composition to the project

Let’s automate the first part using Templify and the second part using NuGet.

Creating the Templify package

I have some bad news for you: you’ll have to take all project setup steps one more time! Create a new solution with a common name, e.g. “templateproject”. Add project references, library references, anything you need for this project to be the ideal base solution for any new project. Here’s an overview of what I am talking about:

Create new Templify project

Next, close Visual Studio and browse to the solution’s root folder location. After installing Templify, a new contect-menu item will be available: “Templify this folder”. Click it!

Templify this folder

After clicking it, a simple screen will be presented, asking you for 4 simple things: Name, Token, Author and Version. Easy! Name is the name for the package. Token is the part of the project name / namespace name / whatever you want to have replace with the next project’s common name. In my case, this will be “templateproject”. Author and version are easy as well.

Templify main screen

Click “Templify”, and behold! Nothing seems to have happened! Except for a small notification in your systray area. But don’t fear: a package has been created for your project and you can now execute the first steps of the scenario described above.

Templify package created

That’s basically it. If you want to redistribute your Templify package, check the C:\Users\%USERNAME%\AppData\Roaming\Endjin\Templify\repo  folder for that.

Creating a NuGet package

For starters, you will need the nuget.exe command-line utility. If that prerequisite is on your machine, you are already half-way. And to be honest: if you read the documentation over at the NuGet CodePlex project page you are there all the way! But I’ll give you a short how-to. First, create a folder structure like this:

  • content (optional)
  • lib (optional)
  • <your package name>.nuspec

In the content folder, simply put anything you would like to add into the project. ASP.NET MVC Views, source code, anything. In the lib folder, add all assembly references tatshould be added.

Next, edit the <your package name>.nuspec file and add relevant details for your package:

1 <?xml version="1.0"?> 2 <package xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 4 <metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> 5 <id>MefDependencyResolver</id> 6 <version>0.0.1</version> 7 <authors>Maarten Balliauw</authors> 8 <requireLicenseAcceptance>false</requireLicenseAcceptance> 9 <description>MefDependencyResolver</description> 10 <summary>MefDependencyResolver</summary> 11 <language>en-US</language> 12 </metadata> 13 </package>

Once that’s done, simply call nuget.exe like so: nuget pack MefDependencyResolver\mefdependencyresolver.nuspec
Note that this can also be done using an MSBUILD command in any project.

If NuGet is finished, a new package should be available, in my above situation the MefDependencyResolver.0.0.1.nupkg file is generated.

Creating a NuGet feed

This one’s easy. You can use an OData feed (see here and here), but what’s even easier: just copy all packages to a folder or network share and point Visual Studio there. Fire up those Visual Studio settings, find the Package Manager node and add your local or network package folder:

Creating a NuGet feed

Done!

Behold! A new project!

So you took all the effort in creating a Templify and NuGet package. Good! Here’s how you can benefit. Whenever a new project should be started, open op an Explorer window, create a new folder, right-click it and select “Templify here”. Fill out the name of the new project (I chose “ProjectCool” because that implies I’m working on a cool project and cool projects are fun!). Select the template to deploy. Next, click “Deploy template”.

Templify Deploy Template

Open up the folder you just created and behold: “ProjectCool” has been created and my first 3 boring tasks are now gone. If I don’t tell my boss I have this tool, I can actually sleep for the rest of the day and pretend I have done this manually!

ProjectCool has been Templified!

Next, open up “ProjectCool” in Visual Studio. Right-click the ASP.NET MVC project and select “Add library package reference…”.

Add library package reference

Select the feed you just created and simply pick the packages to install into this application. Need a specific set of DiaplayTemplates? Create a package for those. Need the company CSS styles for complex web applications? Create a package for that! Need jQuery UI? Create a package for that!

Install NuGet package

Conclusion

I’m totally going for this approach! It speeds up initial project creation without the overhead of maintaining automation packages and such. Using simple tooling that is easy to understand, anyone on your project team can take this approach, both for company-wide Templify and NuGet packages, as well as individual packages.

Personally, I would like to see these two products combined into one, in the scenario outlined here. However I would already be happy if I could also create a company-wide “Templify” feed, ideally integrated with the NuGet tooling.

For fun and leasure, I packaged everything I created in this blog post: TemplifyNuGet.zip (508.23 kb)

Byebye 2010, welcome 2011!

fireworks

Happy New Year 2011! I wish you all the best in your career and personal life. And I know it’s a classic one: I wish you a good health! Some family members have had some serious issues on that part and really, health is the most imprtant thing you need. All the rest depends on that. If you’re healthy, you will do something, that something will earn you money, and money buys you things. An Indian taxi driver in Redmond, Seattle, WA told me this exact lesson this year. I was a bit fuzzy at that time after a long flight from Belgium, Europe, but he is right. Sandeep, happy new year to you to although you may probably not read my blog.

In this kind of posts, just like in 2008 and 2009, I’ll start with looking at the top blog posts.

Top 5 blog posts of 2010

  1. Code performance analysis in Visual Studio 2008 (2009: 3rd; 2008: 2nd) – Visual Studio developer, did you know you have a great performance analysis (profiling) tool at your fingertips?
  2. ASP.NET load balancing and ASP.NET state server (aspnet_state) (2009: 5th; 2008: 3rd) – A how-to on load balancing with ASP.NET. Also related to ASP.NET Session State Partitioning and ASP.NET Session State Partitioning using State Server Load Balancing.
  3. Code based ASP.NET MVC GridView (2009: 2nd; 2008: 4th) – This post gives a shot at a gridview for the ASP.NET MVC framework, built using expressions.
  4. Building an ASP.NET MVC sitemap provider with security trimming (2009: 4th; 2008: 5th) – Building an ASP.NET MVC sitemap provider that can be used with standard ASP.NET sitemap controls.
  5. ASP.NET MVC and the Managed Extensibility Framework (MEF) (newcomer!) – Showing some integration points of the managed extensibility framework with ASP.NET MVC.

It’s stunning to see there’s only one newcomer in this list, ASP.NET MVC and the Managed Extensibility Framework (MEF). All other top posts are from 2008 (!), cover older technology but are still of value. Is this because these posts rank higher in search engines? Is it because people use older technology more then cutting edge technology? I’m really interested in this, as I may shift focus to cover a bit more of the “older” technologies for 2011 if this is indeed the case.

Open-source in 2010

I continued to work on PHPExcel, PHPLinq, PHPPowerPoint, the Windows Azure SDK for PHP (with Microsoft), ASP.NET MVC SiteMap Provider, some contributions to Zend Framework, my port of MEF to PHP and that’s about it I guess.

I’m very happy with the contributors to PHPExcel and the fact that this library is being used so widely. Really great to see! Also, I’ve received some financial support for the other projects and that really helped in getting things forward. I would also like to thank Microsoft and my employer, RealDolmen, for providing much needed development time on these projects.

Presentations in 2010

Ok, presentations. This kind of exploded in 2010. I wanted to do “some” more in 2010, it actually were around 17 on large events and some more at smaller events, our AZUG user group and internal sessions at RealDolmen.

The best thing: out of these 17 large-event sessions, I did 11 abroad throughout Europe. That’s not glamourous life, but it’s great to meet peers from all around the world. I’m absolutely wanting to do more of this in 2011.

The list of sessions can be found on my talks and presentations page. If you want me to speak at your conference, feel free to shoot me an e-mail. I'll be happy to provide you with session proposals. That’s in bold because it’s a hint for all you conference organizers out there :-)

Most valuable professional

image In July 2009, I became an MVP ASP.NET. And in July 2010, this title got renewed. I’m very happy for that, it’s a great honour and a great door-opener for other things I do.

My focus was still on ASP.NET MVC in 2010, but also more and more on Windows Azure. These two make a great combination, and will be the main topics for my blog in 2011 as well.

Traveling in 2010

A lot of traveling in 2010… A lot! I went on a ski vacation and a summer vacation, but next to that I did some traveling for work and conferences as well:

  • Lisbon, Portugal (2 times)
  • London, UK
  • Vienna, Austria. A beautiful city!
  • Helsinki, Finland (2 times). Cold but warm people!
  • Poznan, Poland. Great wodka, cheap wodka and great people!
  • Copenhagen, Denmark
  • Seattle, US

A lot of airmiles this year, too bad they are on separate frequent flyer programs. This year I also discovered www.tripit.com, a great site for tracking everything related to your trip!

Thank you!

I do take credit for all that I did in 2010, but I would also like to thank my company RealDolmen for providing enough room to do some of this during work hours, as well as for challenging me in this. Recruiters often offer great salaries, but this is what I find important. And as far as I know, this is also quite unique in Belgium for a company to do. Thanks guys, really!

My family is also great, especially my wife. I’m often out of the house at evenings to various local events, writing blog posts, traveling abroad or just toying with technology. Thanks for letting me do this, I owe all of you big time!

Next, thank YOU too! For reading my blog, following me on Twitter and providing me insights and inspiration to do what I love to do. Feel free to ask me questions and to challenge me.

Summary and look ahead

All traveling and presentations weighed a bit on my blogging habits. Down from 79 posts to 48. It’s been a busy year, both for professional and community work. I hope to be able to invest even more in the latter, but we’ll see.

Oh right, I did some articles for PHP architect, .NET magazine, Technet, the WIndows Azure website, … I also became a cloud leader apparently, even though I’m just a technology enthousiast with an opinion. For 2011, I will probably do a little less articles but that’s in favour of writing a book with some other guys. It’ll be great, I promise. But more on that later.

Enjoy 2011, I definitely will! Oh and Sandeep, if I’m in Redmond again I definitely want you as my taxi driver.

The quickest way to a VPN: Windows Azure Connect

Windows Azure Connect endpoint installerFirst of all: Merry Christmas in advance! But to be honest, I already have my Christmas present… I’ll give you a little story first as it’s winter, dark outside and stories are better when it’s winter and you are reading this post n front of your fireplace. Last week, I received the beta invite for Windows Azure Connect, a simple and easy-to-manage mechanism to setup IP-based network connectivity between on-premises and Windows Azure resources. Being targeted at interconnecting Windows Azure instances to your local network, it also contains a feature that allows interconnecting endpoints. Interesting!

Now why would that be interesting… Well, I recently moved into my own house, having lived with my parents since birth, now 27 years ago. During that time, I bought a Windows Home Server that was living happily in our home network and making backups of my PC, my work laptop, my father’s PC and laptop and my brother’s laptop. Oh right, and my virtual server hosting this blog and some other sites. Now what on earth does this have to do with Windows Azure Connect? Well, more then you may think…

I’ve always been struggling with the idea on how to keep my Windows Home Server functional, between the home network at my place and the home network at my parents place. Having tried PPTP tunnels, IPSEC, OpenVPN, TeamViewer’s VPN capabilities, I found these solutions working but they required a lot of tweaking and installation woes. Not to mention that my ISP (and almost all ISP’s in Belgium) blocks inbound TCP connections to certain ports.

Untill I heard of Windows Azure Connect and that tiny checkbox on the management portal that states “Allow connections between endpoints in group”. Aha! So I started installing the Windows Azure Connect connector on all machines. A few times “Next, I accept, Next, Finish” later, all PC’s, my virtual server and my homeserver were talking cloud with each other! Literally, it takes only a few minutes to set up a virtual network on multiple endpoints. And it also routes through proxies, which means that my homeserver should even be able to make backups of my work laptop when I’m in the office with a very restrictive network. Restrictive for non-cloudians, that is :-)

Installing Windows Azure Connect connector

This one’s easy. Navigate to http://windows.azure.com, and in the management portal for Windows Azure Connect, click “Install local endpoint”.

Windows Azure Connect management

You will be presented a screen containing a link to the endpoint installer.

Installing Windows Azure Connect

Copy this link and make sure you write it down as you will need it for all machines that you want to join in your virtual network. I tried just copying the download to all machines and installing from there, but that does not seem to work. You really need a fresh download every time.

Interconnecting machines

This one’s reall, really easy. I remember configuring Cisco routers when I was on school, but this approach is a lot easier I can tell you. Navigate to http://windows.azure.com and open the Windows Azure Connect management interface. Click the “Create group” button in the top toolbar.

Windows Azure Connect interconnecting

Next, enter a name and an optional description for your virtual network. Next, add the endpoints that you’ve installed. Note that it takes a while for them to appear, this can be forced by going to every machine that you installed the connector for and clicking the “Refresh” option in the system tray icon for Windows Azure Connect. Anyway, here are my settings:

Windows Azure Connect create group

Make sure that you check “Allow connections between endpoints in group”. And eh… that’s it! You now have interconnected your machines on different locations in about five minutes. Cloud power? For sure!

As a side node: it would be great if one endpoint could be joined to multiple “groups” or virtual networks. That would allow me to create a group for other siuations, and make my PC part of all these groups.

Some findings

Just for the techies out there, here’s some findings… Let’s start with doing an ipconfig /all on one of the interconnected machines:

Windows Azure Connect ipv6

Windows Azure Connect really is a virtual PPP adapter added to your machine. It operates over IPv6. Let’s see if we can ping other machines. Ebh-vm05 is the virtual machine hosting my blog, running in a datacenter near Brussels. I’m issuing this ping command from my work laptop in my parents home network near Antwerp. Here goes:

Windows Azure Connect ping

Bam! Windows Azure Connect even seems to advertise hostnames on the virtual network! I like this very, very much! This would mean I can also do remote desktop between machines, even behind my company’s restrictive proxy. I’m going to try that one on monday. Eat that, corporate IT :-)

One last thing I’m interested in: the IPv6 addresses of all connected machines seem to be in different subnets. Let’s issue a traceroute as well.

Windows Azure Connect trace route

Sweet! It seems that there’s routing going on inside Windows Azure Connect to communicate between all endpoints.

As a side node: yes, those are high ping times. But do note that I was at my parents home when taking this screenshot, and the microwave was defrosting Christmas meals between my laptop and the wireless access point.

Conclusion

I’m probably abusing Windows Azure Connect doing this. However, it’s a great use case in my opinion and I really hope Microsoft keeps supporting this. What would even be better is that they offered Windows Azure Connect in the setup I described above for home users as well. It would be a great addition to Windows Intune as well!

Windows Azure Remote Desktop Access

The latest relase of the WIndows Azure platform, portal and tools (check here) includes support for one of the features announced at PDC last month: remote desktop access to your role instances. This feature is pretty easy to use and currently allows you to deploy a preconfigured VM with IIS where you can play with the OS. No real application needed!

Here’s how:

  1. Create a new Cloud Service and add one Web Role. This should be the result:

    image
  2. Once that is done, right click the Cloud Service and select “Publish…”
  3. In the publish dialog, click “Confiure Remote Desktop connections…”
  4. Create (or select) a certificate, make sure you also export the private key for it.
  5. Enter some credentials and set te expiration date for the account to some far future.
  6. Here’s an example of how that can look like:

    image
  7. Don’t publish yet!
  8. Navigate to http://windows.azure.com and create a new Hosted Service. In this hosted service, upload the certificate you just created:

    image
  9. Once that is done, switch back to Visual Studio, hit the Publish button and sit back while your deployment is being executed.
  10. At a given moment, you will see that deployment is ready.
  11. Switch back to your browser, click your instance and select “Connect” in the toolbar:

    image
  12. Enter your credentials, prefixed with \. E.g. “\maarten”. This is done to strip off the Windows domain from the credentials entered.
  13. RDP happyness!

    image

Writing for the Windows Azure for PHP portal

image

I actually just noticed it has been a while since I did a blog post. I also know that writing about this is not really a good idea in the blogosphere. Unless… it’s for a good reason!

The good reason for not being that active on my blog lately is the fact that I’m producing content for Microsoft’s Interoperability team. Have you ever wanted to start working with Windows Azure and PHP? No idea where to start? Meet the official portal: Developing Applications for Azure with PHP.

I’ve currently posted some tutorials and scenarios out there, but there’s more to come. Here’s a list of what’s currently available:

So whenever you think I’m relaxing and doing nothing, check http://azurephp.interoperabilitybridges.com for new content. By the way, if you are doing PHP and Azure, drop me a line. It’s always good to know and maybe I can be of help.

Stay tuned for more on this!

MvcSiteMapProvider 2.2.0 released

I’m proud to announce that MvcSiteMapProvider 2.2.0 has just been uploaded to CodePlex. It should also be available through NuPack in the coming hours. This release has taken a while, but that’s because I’ve been making some important changes...

MvcSiteMapProvider is, as the name implies, an ASP.NET MVC SiteMapProvider implementation for the ASP.NET MVC framework. Targeted at ASP.NET MVC 2, it provides sitemap XML functionality and interoperability with the classic ASP.NET sitemap controls, like the SiteMapPath control for rendering breadcrumbs and the Menu control.

In this post, I’ll give you a short update on what has changed as well as some examples on how to use newly introduced functionality.

Changes in MvcSiteMapProvider 2.2.0

  • Increased stability
  • HtmlHelpers upgraded to return MvcHtmlString
  • Templated HtmlHelpers have been introduced
  • New extensibility point: OnBeforeAddNode and OnAfterAddNode
  • Optimized sitemap XML for search engine indexing

Templated HtmlHelpers

The MvcSiteMapProvider provides different HtmlHelper extension methods which you can use to generate SiteMap-specific HTML code on your ASP.NET MVC views like a menu, a breadcrumb (sitemap path), a sitemap or just the current node’s title.

All helpers in MvcSiteMapProvider are make use of templates: whenever a node in a menu is to be rendered, a specific partial view is used to render this node. This is based on the idea of templated helpers. The default templates that are used can be found on the downloads page. Locate them under the Views/DisplayTemplates folder of your project to be able to customize them.

When creating your own templates for MvcSiteMapProvider's helpers, the following model objects are used and can be templated:

  • Html.MvcSiteMap().Menu() uses:
    MvcSiteMapProvider.Web.Html.Models.MenuHelperModel and MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModel
  • Html.MvcSiteMap().SiteMap() uses:
    MvcSiteMapProvider.Web.Html.Models.SiteMapHelperModel and MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModel
  • Html.MvcSiteMap().SiteMapPath() uses:
    MvcSiteMapProvider.Web.Html.Models.SiteMapPathHelperModel and MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModel
  • Html.MvcSiteMap().SiteMapTitle()
    MvcSiteMapProvider.Web.Html.Models.Situses:eMapTitleHelperModel

The following template is an example for rendering a sitemap node represented by the MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModel model.

1 <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModel>" %> 2 <%@ Import Namespace="System.Web.Mvc.Html" %> 3 4 <% if (Model.IsCurrentNode && Model.SourceMetadata["HtmlHelper"].ToString() != "MvcSiteMapProvider.Web.Html.MenuHelper") { %> 5 <%=Model.Title %> 6 <% } else if (Model.IsClickable) { %> 7 <a href="<%=Model.Url %>"><%=Model.Title %></a> 8 <% } else { %> 9 <%=Model.Title %> 10 <% } %>

New extensibility point

In the previous release, a number of extensibility points have been introduced. I blogged about them before. A newly introduced extensibility point is the ISiteMapProviderEventHandler . A class implementing MvcSiteMapProvider.Extensibility.ISiteMapProviderEventHandler can be registered to handle specific events, such as when adding a SiteMapNode.

Here’s an example to log all the nodes that are being added to an MVC sitemap:

1 public class MySiteMapProviderEventHandler : ISiteMapProviderEventHandler 2 { 3 public bool OnAddingSiteMapNode(SiteMapProviderEventContext context) 4 { 5 // Should the node be added? Well yes! 6 return true; 7 } 8 9 public void OnAddedSiteMapNode(SiteMapProviderEventContext context) 10 { 11 Trace.Write("Node added: " + context.CurrentNode.Title); 12 } 13 }

Optimized sitemap XML for SEO

Generating a search-engine friendly list of all nodes in a sitemap was already possible. This functionality has been vastly improved with two new features:

  • Whenever a client sends an HTTP request header with Accept-encoding set to a value of gzip or deflate, the XmlSiteMapResult class (which is also used internally in the XmlSiteMapController) will automatically compress the sitemap using GZip compression.
  • Whenever a sitemap exceeds 50.000 nodes, the XmlSiteMapController will automatically split your sitemap into a sitemap index file (sitemap.xml) which references sub-sitemaps (sitemap-1.xml, sitemap-2.xml etc.) as described on http://www.sitemaps.org/protocol.php.

For example, if a website contains more than 50.000 nodes, the sitemap XML that is generated will look similar to the following:

1 <?xml version="1.0" encoding="utf-8" ?> 2 <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> 3 <sitemap> 4 <loc>http://localhost:1397/sitemap-1.xml</loc> 5 </sitemap> 6 <sitemap> 7 <loc>http://localhost:1397/sitemap-2.xml</loc> 8 </sitemap> 9 </sitemapindex>

This sitemap index links to sub-sitemap files where all nodes are included.

Scale-out to the cloud, scale back to your rack

That is a bad blog post title, really! If Steve and Ryan have this post in the Cloud Cover show news I bet they will make fun of the title. Anyway…

Imagine you have an application running in your own datacenter. Everything works smoothly, except for some capacity spikes now and then. Someone has asked you for doing something about it with low budget. Not enough budget for new hardware, and frankly new hardware would be ridiculous to just ensure capacity for a few hours each month.

A possible solution would be: migrating the application to the cloud during capacity spikes. Not all the time though: the hardware is in house and you may be a server-hugger that wants to see blinking LAN and HDD lights most of the time. I have to admit: blinking lights are cool! But I digress.

Wouldn’t it be cool to have a Powershell script that you can execute whenever a spike occurs? This script would move everything to Windows Azure. Another script should exist as well, migrating everything back once the spike cools down. Yes, you hear me coming: that’s what this blog post is about.

For those who can not wait, here’s the download: ScaleOutToTheCloud.zip (2.81 kb)

Schematical overview

Since every cool idea goes with fancy pictures, here’s a schematical overview of what could happen when you read this post to the end. First of all: you have a bunch of users making use of your application. As a good administrator, you have deployed IIS Application Request Routing as a load balancer / reverse proxy in front of your application server. Everyone is happy!

IIS Application Request Routing

Unfortunately: sometimes there are just too much users. They keep using the application and the application server catches fire.

Server catches fire!

It is time to do something. Really. Users are getting timeouts and all nasty error messages. Why not run a Powershell script that packages the entire local application for WIndows Azure and deploys the application?

Powershell to the rescue

After deployment and once the application is running in Windows Azure, there’s one thing left for that same script to do: modify ARR and re-route all traffic to Windows Azure instead of that dying server.

Request routing Azure

There you go! All users are happy again, since the application is now running in the cloud one 2, 3, or whatever number of virtual machines.

Let’s try and do this using Powershell…

The Powershell script

The Powershell script will rougly perform 5 tasks:

  • Load settings
  • Load dependencies
  • Build a list of files to deploy
  • Package these files and deploy them
  • Update IIS Application Request Routing servers

Want the download? There you go: ScaleOutToTheCloud.zip (2.81 kb)

Load settings

There are quite some parameters in play for this script. I’ve located them in a settings.ps1 file which looks like this:

# Settings (prod) $global:wwwroot = "C:\inetpub\web.local\" $global:deployProduction = 1 $global:deployDevFabric = 0 $global:webFarmIndex = 0 $global:localUrl = "web.local" $global:localPort = 80 $global:azureUrl = "scaleout-prod.cloudapp.net" $global:azurePort = 80 $global:azureDeployedSite = "http://" + $azureUrl + ":" + $azurePort $global:numberOfInstances = 1 $global:subscriptionId = "" $global:certificate = "C:\Users\Maarten\Desktop\cert.cer" $global:serviceName = "scaleout-prod" $global:storageServiceName = "" $global:slot = "Production" $global:label = Date

Let’s explain these…

$global:wwwroot The file path to the on-premise application.
$global:deployProduction Deploy to Windows Azure?
$global:deployDevFabric Deploy to development fabric?
$global:webFarmIndex The 0-based index of your webfarm. Look at IIS manager and note the order of your web farm in the list of webfarms.
$global:localUrl The on-premise URL that is registered in ARR as the application server.
$global:localPort The on-premise port that is registered in ARR as the application server.
$global:azureUrl The Windows Azure URL that will be registered in ARR as the application server.
$global:azurePort The Windows Azure port that will be registered in ARR as the application server.
$global:azureDeployedSite The final URL of the deployed Windows Azre application.
$global:numberOfInstances Number of instances to run on Windows Azure.
$global:subscriptionId Your Windows Azure subscription ID.
$global:certificate
Your certificate for managing Windows Azure.
$global:serviceName Your Windows Azure service name.
$global:storageServiceName The Windows Azure storage account that will be used for uploading the packaged application.
$global:slot The Windows Azure deployment slot (production/staging)
$global:label The label for the deployment. I chose the current date and time.

Load dependencies

Next, our script will load dependencies. There is one additional set of CmdLets tha tyou have to install: the Windows Azure management CmdLets available at http://code.msdn.microsoft.com/azurecmdlets.

Here’s the set we load:

# Load required CmdLets and assemblies $env:Path = $env:Path + "; c:\Program Files\Windows Azure SDK\v1.2\bin\" Add-PSSnapin AzureManagementToolsSnapIn [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Administration")

Build a list of files to deploy

In order to package the application, we need a text file containing all the files that should be packaged and deployed to Windows Azure. This is done by recursively traversing the directory where the on-premise application is hosted.

 

$filesToDeploy = Get-ChildItem $wwwroot -recurse | where {$_.extension -match "\..*"} foreach ($fileToDeploy in $filesToDeploy) { $inputPath = $fileToDeploy.FullName $outputPath = $fileToDeploy.FullName.Replace($wwwroot,"") $inputPath + ";" + $outputPath | Out-File FilesToDeploy.txt -Append }

Package these files and deploy them

I have been polite and included this both for development fabric as well as Windows Azure fabric. Here’s the packaging and deployment code for development fabric:

# Package & run the website for Windows Azure (dev fabric) if ($deployDevFabric -eq 1) { trap [Exception] { del -Recurse ScaleOutService continue } cspack ServiceDefinition.csdef /roleFiles:"WebRole;FilesToDeploy.txt" /copyOnly /out:ScaleOutService /generateConfigurationFile:ServiceConfiguration.cscfg # Set instance count (Get-Content ServiceConfiguration.cscfg) | Foreach-Object {$_.Replace("count=""1""","count=""" + $numberOfInstances + """")} | Set-Content ServiceConfiguration.cscfg # Run! csrun ScaleOutService ServiceConfiguration.cscfg /launchBrowser }

And here’s the same for Windows Azure fabric:

# Package the website for Windows Azure (production) if ($deployProduction -eq 1) { cspack ServiceDefinition.csdef /roleFiles:"WebRole;FilesToDeploy.txt" /out:"ScaleOutService.cspkg" /generateConfigurationFile:ServiceConfiguration.cscfg # Set instance count (Get-Content ServiceConfiguration.cscfg) | Foreach-Object {$_.Replace("count=""1""","count=""" + $numberOfInstances + """")} | Set-Content ServiceConfiguration.cscfg # Run! (may take up to 15 minutes!) New-Deployment -SubscriptionId $subscriptionId -certificate $certificate -ServiceName $serviceName -Slot $slot -StorageServiceName $storageServiceName -Package "ScaleOutService.cspkg" -Configuration "ServiceConfiguration.cscfg" -label $label $deployment = Get-Deployment -SubscriptionId $subscriptionId -certificate $certificate -ServiceName $serviceName -Slot $slot do { Start-Sleep -s 10 $deployment = Get-Deployment -SubscriptionId $subscriptionId -certificate $certificate -ServiceName $serviceName -Slot $slot } while ($deployment.Status -ne "Suspended") Set-DeploymentStatus -Status "Running" -SubscriptionId $subscriptionId -certificate $certificate -ServiceName $serviceName -Slot $slot $wc = new-object system.net.webclient $html = "" do { Start-Sleep -s 60 trap [Exception] { continue } $html = $wc.DownloadString($azureDeployedSite) } while (!$html.ToLower().Contains("<html")) }

Update IIS Application Request Routing servers

This one can be done by abusing the .NET class Microsoft.Web.Administration.ServerManager.

# Modify IIS ARR $mgr = new-object Microsoft.Web.Administration.ServerManager $conf = $mgr.GetApplicationHostConfiguration() $section = $conf.GetSection("webFarms") $webFarms = $section.GetCollection() $webFarm = $webFarms[$webFarmIndex] $servers = $webFarm.GetCollection() $server = $servers[0] $server.SetAttributeValue("address", $azureUrl) $server.ChildElements["applicationRequestRouting"].SetAttributeValue("httpPort", $azurePort) $mgr.CommitChanges()

Running the script

Of course I’ve tested this to see if it works. And guess what: it does!

The script output itself is not very interesting. I did not add logging or meaningful messages to see what it is doing. Instead you’ll just see it working.

Powershell script running

Once it has been fired up, the Windows Azure portal will soon be showing that the application is actually deploying. No hands!

Powershell deployment to Azure

After the usual 15-20 minutes that a deployment + application first start takes, IIS ARR is re-configured by Powershell.

image

And my local users can just keep browsing to http://farm.local which now simply routes requests to Windows Azure. Don’t be fooled: I actually just packaged the default IIS website and deployed it to Windows Azure. Very performant!

image

Conclusion

It works! And it’s fancy and cool stuff. I think this may be a good deployment and scale-out model in some situations, however there may still be a bottleneck in the on-premise ARR server: if this one has too much traffic to cope with, a new burning server is in play. Note that this solution will work for any website hosted on IIS: custom made ASP.NET apps, ASP.NET MVC, PHP, …

Here’s the download: ScaleOutToTheCloud.zip (2.81 kb)

Windows Phone 7 First Impressions

Windows Phone 7Back in june of this year, I received a very surprising e-mail stating that I would receive a Windows Phone 7 developer device. The reason for this? No, not that I’m handsome. But the fact that I paid $99 for listing an application in the marketplace that they were hoping me to port to Windows Phone 7. The wait continued: july? No phone. August? No phone. By september I thought I was not getting a Windows Phone 7 anymore. Until this week: another e-mail stating that the device was shipped. And today, FedEx kindly handed me over a developer device.

After installing my SIM card and starting the phone, I was welcomed by the nice looking Windows Phone 7 tiles. And that is where the rest of my journey started…

Disclaimer: This device is not a production device. It is a prototype developed by LG and I have absolutely no clue how this thing will look like and perform in the production model. Next, I have only used this phone for a few hours yet. Therefore do not base final judgements of the product on this blog post.

By the way, seems like Scott Hanselman also received a prototype phone and blogged about his experience.

Things I like

Here’s a list of the things I really, really like:

  • Windows Live, Google, Yahoo and Exchange are data sources for contacts and calendar information. I added my Windows Live account, Facebook, GMail and work Exchange account and WP7 is happily synchronizing everything.
  • With all that synching, WP7 seems to identify contacts: my wife’s Windows Live contact details, Facebook details and GMail details are all combined into one contact on the phone which is extremely useful. All contact information is centralized in that way.
  • The photo camera (5 MP) has a dedicated button. A button that also lets you take pictures if the phone is turned off! No need for a 20 seconds boot time if you want to quickly take a picture: just push the button and take a picture.
  • The tiles on the main screen are a very refreshing UI concept. Also, the UI is very smooth and fast compared with any other phone I used in the past.
  • Everything is very straightforward: you can get up and running in no time.
  • This model has a hardware keyboard which is a nice addition. Typing using the on-screen keyboard works but I do have thick fingers that are wrong sometimes. No problem in English as the English dictionary is helping as you type, but there’s no Dutch dictionary in this one yet which gives me a lot of mistakes. Unless I use the hardware keyboard, which I like better than on-screen.

Things I miss

There are some things I miss and may have me ending up with 2 phones in my pocket: my WP6 and WP7 phone. Here’s a list of things I miss:

  • A decent Twitter application. There's an app for that but not yet something like PockeTwit which I used on WP6.
  • Facebook is nicely integrated, except I can not find a place to update my status. Writing on people’s wall and commenting on people’s posts is possible but I seem to be missing a place where I can just enter “What’s on my mind?” Found here how it works.
  • There’s no such thing as Outlook synchronization! I have a GMail account for e-mail and tend to maintain contacts and calendar in good old Outlook. After looking at how to synchronize these I haven’t found a good manner to synchronize these contacts and calendar. My current solution was a bulk import into Windows Live contacts and calendar which works but is not very straightforward if you are used to just ActiveSyncing everything. Actually I started liking Windows Live for this matter. So maybe you'll miss it but I no longer do.
  • I have TomTom on my WP6 phone, does anyone know if they will release a WP7 version that does not eat your data plan?
  • Tethering! Really, every modern phone supports this!

Things I dislike

Another list of items… I dislike:

  • I don’t really like the Zune software. It appears very bloated and requires a lot of clicking to get some basic stuff done.
  • Fortunately I have a data plan with my cellphone operator. If you do not have such a thing, the WP7 will cost you a lot of money. If you would turn off data on the device, it will have less functionality.
  • There’s no Outlook synchronization. I fixed this with a workaround (see “Things I miss”), but would rather see this supported out-of-the-box.
  • Battery life seems rather short (+/ 1,5 day before having to recharge?)
  • No tethering???

Conclusion

If you look at the lists above, you will notice that I like the device and OS. There’s some lacking functionality and apps, but I’m sure these will be available soon after the release. It’s very surprising how smooth this device works and how easy it is to work with. Looking forward to the first official devices! And hope they will sync with Outlook and will support tethering...

Using MvcSiteMapProvider throuh NuPack

NuPackProbably you have seen the buzz around NuPack, a package manager for .NET with thight integration in Visual Studio 2010. NuPack is a free, open source developer focused package management system for the .NET platform intent on simplifying the process of incorporating third party libraries into a .NET application during development. If you download and install NuPack into Visual Studio, you can now reference MvcSiteMapProvider with a few simple clicks!

From within your ASP.NET MVC 2 project, right click the project file and use the new “Add Package Reference…” option.

Add package reference

Next, a nice dialog shows up where you can just pick a package and click “Install” to download it and add the necessary references to your project. The packages are retrieved from a central XML feed, but feel free to add a reference to a directory where your corporate packages are stored and install them through NuPack. Anyway: MvcSiteMapProvider. Just look for it in the list and click “Install”.

MvcSiteMapProvider in NuPack

Next, MvcSiteMapProvider will automatically be downloaded, added as an assembly reference, a default Mvc.sitemap file is added to your project and all configuration in Web.config takes place without having to do anything! I’m sold :-)

Disclaimer for some: I’m not saying NuPack is the best package manager out there nor that it is the best original idea ever invented. I do believe that the tight integration in VS2010 will make NuPack a good friend during development: the process of downloading and including third party components in your application becomes frictionless. That’s the aim for NuPack, and also the reason why I believe this tool matters and will matter a lot!