Sunday, March 08, 2009

Considering Windows Azure (TechDays presentation)

Here’s the first of the two breakout presentations I did at Microsoft TechDays here in Helsinki on the 5th and 6th of March 2009. This presentation was about Windows Azure, and what we at eCraft have learned from considering porting several applications to it. This was not a particularly technical session, I focused on the slightly more philosophical side, by looking at Azure and Cloud applications from a bit of a business perspective as well as an architectural one. I’ll try to put together a post or two later on about a couple of the specifics in the presentation, perhaps on how I see the business impact of the whole thing possibly playing out.

You can also find the presentation on Slideshare.net here.

Monday, November 10, 2008

SqlCE and Entity Framework maybe broken on x64

I’ve been running on a 64 bit version of Windows for the first time the past week, and while most things have worked fine I had one problem that I had a hard time figuring out. An existing project, that worked fine before the upgrade, refused to compile. I also upgraded it to SP1 of Visual Studio 2008, so there were two possible sources for problems.

In my project I have a local SQL Compact (CE) 3.5 database

I’m using the Entity Framework in my application.

The application compiled fine, but when I tried to to run it I got the following error:

"The specified store provider cannot be found in the configuration, or is not valid."

I first thought this was related to my newly installed Vista and to moving to Visual Studio 2008 SP1. But then I stumbled across the following article, where someone else was having the same problem:

http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=3422883&SiteID=1

While the post seemed to be dealing with the beta bits of SP1, it seems what it boils down to is that the provider for SQL CE is broken (missing) on x64. So what I need to do is to compile for x86 (32 bits) instead. “Runs natively in the 64-bit environment”, indeed! (borrowed from the SQL CE product page at microsoft.com)

Most of you probably know how to change this, but in case you don’t I’m including the instructions here. So in order to compile for x86 specifically (instead of “Any CPU” which is the default) you need to add a new configuration for that. The easiest way is to click on the dropdown in the VS menu:

image

and choose “Configuration Manager…”. In the next dialog click the dropdown in the Platform-column.

image

In the popup you can create a new platform (choose x86). That should be it.

Thursday, October 30, 2008

My cloud experience during the Ray Ozzie PDC Keynote

image A lot of people have already blogged about the keynote and commented on the applications shown, so I won’t go into that, apart from saying that I really believe in the model, but I wish they’d found better examples to illustrate it. However, the technology looks fantastic and I’m a big believer in cloud computing. But that’s not the topic of this post. I’ll post more about that later.

Anyway, I was having my own pretty good cloud experience during the keynote, but not on Microsoft Azure. For a while now we’ve been trying to figure out how we want to host our new Sproodle SaaS offering. We’ve been looking into different options ranging from hosting it ourselves (not a good idea) to hosting it as an application somewhere (now we’re getting into Azure-territory, but more on that in another post). One option we’ve explored is using one of several hosting companies that offer you virtual machines in their own hardware, thus saving you from having to invest in that yourself. One such company is Amazon, with their Elastic Compute Cloud (EC2) service. They recently started offering Windows-based virtual machines, which certainly is very interesting.

Amazon Web ServicesOn Sunday we decided we’d try to deploy our Sproodle product into EC2. We were all fired up and ready to go, but unfortunately our plan was foiled because the hotel bar didn’t have a wireless network. It’s kind of hard to put something up in the cloud without a network connection…

So, on Monday, before and during the Ray Ozzie keynote, I set up an EC2 account, created a Windows Server 2003 virtual machine with SQL Server, and deployed our application to it. Creating this machine in the cloud and getting our software up and running on it took 2,5 hours. Getting the Windows Server 2003 virtual box up and running took about 30 minutes. The reason deploying the software took 2 hours had more to do with having to mess around with some nasty config file insanity than with Amazon. Although having to copy files over a remote desktop connection is not exactly the fastest thing in the world. I should have set up some other deployment method, but since this was more of a trial than a real world deployment I decided not to bother with it.

To summarize I think it’s pretty cool to be able to set up a hosted virtual machine complete with our application in less than three hours. EC2 is a pretty cool service, very much oriented around pay-as-you-go (they charge for how long you have your machine running and for how much data you transfer).

Later you’ll find out how long it took us to deploy Sproodle on Microsoft Azure. Yes, we did it already :).

Sunday, October 19, 2008

Silverlight navigation patterns – what do users expect?

image During my presentation at Microsoft DevDay a few days ago I promised to share the code I was showing there. Here’s the first set, with more to follow (maybe in a few days, depending on my schedule).

During the presentation I was talking about how users do not care about what technology was used for making the application (obviously), and instead they just expect the application to behave like other similar or related applications. So, to a user, a Silverlight application is just like any other web application because they use a browser to access it. If the technology itself has certain limitations that is of no interest to the user.

Because Silverlight is heavily sandboxed you can only get access to some of the things going on in the browser, and the back- and forward-buttons (and history management) is not among those. Still, being able to use the back- and forward-buttons is something users expect to be able to do. There’s different ways to solve this, but many of them end up being either browser-specific in one way or the other. However, a month or so ago I came across a post by Jordan Knight that shows an implementation based on features introduced in ASP.NET as part of .NET 3.5 SP1. The code I showed in my presentation was more or less directly influenced/copied from his approach, so all the credit for this approach belongs to him.

image For the DevDay-presentation I made a simple sample application, pictured on the right. There are three buttons, with which the user moves to different parts (modules) of the application.

When the user presses one of the navigation buttons the new position gets added to the browser history.When the user clicks the forward- or back-buttons (or uses the browser history to select a previous position) the application is notified of this and shows the appropriate module.

So how does this work? For a full explanation I really recommend that you read Jordan Knight’s original post, as the sample I made doesn’t really add anything new to it and his explanation is very detailed and easy to follow.

The principle behind the technique Jordan describes is that a bit of JScript is used as glue between the browser and the Silverlight application, and this enables the Silverlight to react to history-related events in the browser.

text_binary

Download the code here.

 

The interesting parts are in the following files:

  • SilverlightBrowserNavigationTestPage.aspx
    Here the History.js is loaded, and the OnPluginLoaded-event on the Silverlight plugin is wired up to an event handler in History.js.
  • HistoryManager.cs
    Used for interfacing between JScript (History.js) and the rest of the Silverlight application.
  • App.xaml.cs
    Here the HistoryManager is instantiated, and a new property is introduced (History) to expose it to the rest of the application.
  • Page.xaml.cs
    Events fired by the HistoryManager when the user uses Back/Forward are handled here, and the appropriate module is shown.

Enjoy the sample.

Saturday, October 18, 2008

Silverlight Experiences at Microsoft WebDay

I gave a presentation on Thursday (the 16th of October) at Microsoft WebDay here in Helsinki. The presentation was about what we've learned while developing our new product Sproodle using Microsoft Silverlight. The focus was not so much on the technical details but on what kind of experiences we've had with the technology and what we've learned from using it.

The recording from the presentation (in Finnish) will be up on Codezone in a few days or so, but if you just want to have a look at the slides you can find them below.

I think the presentation went well, based on the feedback I got (hey, it was even called "epic" in a comment on this blog).

During the presentation I promised to post (at least some of) the samples I showed, and I'll try to get them up during the weekend.

Anyway, here are the slides:

 

View SlideShare presentation or Upload your own. (tags: microsoft silverlight)

I noticed that Slideshare butchered a couple of the slides a bit (fontsizes and such), but it's close enough.

Thursday, September 04, 2008

Bug in SQL Compact, ADO.NET Entity Framework and VS 2008 SP1

I just upgraded my beta version of Visual Studio 2008 SP1 to the final (rtm) version, and noticed that code that used to work on the SP1 beta no longer did. The offending piece of code was a LINQ query where I was querying out some stuff from my entity model.

The error message I was getting said "The ntext and image data types cannot be used in WHERE, HAVING, GROUP BY, ON, or IN clauses, except when these data types are used with the LIKE or IS NULL predicates." which didn't really make sense, since I wasn't using ntext for any columns.

As it turns out, there is a bug in there, and for more information (and a workaround that's a bit of a pain in the butt) please look here: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3746251&SiteID=1.

I'm not sure if this problem exists only with the Entity Framework or in any LINQ to SQL Compact scenario as well, but I'm assuming it's there in both.

This is really not so great, because we have a couple of projects at work where we're using SQL Compact and LINQ together, and we've been hoping to go to Visual Studio 2008 SP1 because of some of the new features in WPF and other things. So I really hope there will be a fix for this.

Monday, June 02, 2008

Using the Google Chart API in a WPF application

If you haven't had a look at the Google Chart API I definitely recommend you do so. It can be a good, light alternative to investing in a more complete charting package. And honestly, most of the extra stuff offered by the 3rd party charting components out there is just eye candy that detracts from the information you chart should communicate.

So, with the Google Chart API you can easily put charts like this in your web application or page:

All you need to do is put an img on your page, and set it's src to a url that contains some Google Chart magic. The url for the chart above looks like this:

Granted, the query arguments are quite complex. But Google has some nice documentation for it, and in the end it's not so bad. Here's a simple example:

The url for this puppy is:

The way you talk to Google Chart is through a series of parameters, separated with an ampersand (&). The url above contains three parameters, as follows:

cht=lc Set the chart type to line chart.
chs=150x100 Set the size of the chart to a width of 150 and a height of 100.
chd=t:10,70,50,40,80,5,25,95 The data points for the chart, as comma-separated values.

So, as you can see, pretty simple stuff.

But what about using this in desktop applications, and WPF applications in particular? Since all Google Chart does is generates an image based on parameters you pass to it in the URL, it can be used in XAML through the Image control. Like this:

<Image Width="150" Height="100" Source="http://chart.apis.google.com/chart?cht=lc&amp;chs=150x100&amp;chd=t:10,70,50,40,80,5,25,95"/>

Note that the ampersands (&) had to be encoded as "&amp;" in the XAML.

Here's a screenshot of the XAML above being used in a little application:

image

Ok, so that works nicely. But dealing with the url, and in particular passing the data point for the chart to the API that way is a little bit ugly, and certainly feels very crude compared to how you usually do things in WPF. So what can be done to improve this? One thing that comes to mind is using a value converter to convert a list of values to the url-format that Google Chart wants. Here's an example of that:

[ValueConversion(typeof(IList), typeof(string))]
    public class ListToTextEncodingConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            IList valueList = (IList)value;
            string baseUrl = (string)parameter;
            if (valueList == null || baseUrl == null)
                return string.Empty;
 
            string valueString = "";
            CultureInfo usCulture = new CultureInfo("en-us");
 
            foreach (object item in valueList)
            {
                double? val = item as double?;
                if (val.HasValue)
                {
                    if (valueString.Length > 0)
                        valueString += ",";
                    valueString += val.Value.ToString(usCulture.NumberFormat);
                }
            }
 
            return baseUrl + "&chd=t:" + valueString;
        }
 
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return Binding.DoNothing;
        }
    }

It accepts something that implements IList, and tries to find doubles in it, and constructs the url string from that. In addition it accepts the rest of the parameters for Google Chart as a parameter.

And here's a snippet of XAML that uses that value converter to display a chart:

<Window x:Class="WpfSample.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfSample"
    xmlns:converters="clr-namespace:WpfSample.ValueConverters.ChartDataEncodingConverters"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <local:SampleData x:Key="SampleData"/>
        <converters:ListToTextEncodingConverter x:Key="ListToTextEncodingConverter"/>
    </Window.Resources>
    <Grid>
        <Image Width="250" Height="150"
               Source="{Binding Source={StaticResource SampleData}, 
                                Converter={StaticResource ListToTextEncodingConverter},
                                ConverterParameter='http://chart.apis.google.com/chart?cht=lc&amp;chs=250x150&amp;chds=0,30'}"/>
    </Grid>
</Window>

Oh, and please not that the ConverterParameter seems to screw up the WPF designer in Visual Studio 2008, I haven't looked into whether anything can be done about that. But it compiles and runs fine.

SampleData is just a set of values, you could of course use whatever you want for your data source, perhaps pull something from a database and use Linq to project it into a list of double values. Here's the class that creates the sample data:

public class SampleData : List<double>
{
    public SampleData()
    {
        Add(10);
        Add(20);
        Add(15.2);
        Add(12);
        Add(21);
        Add(17);
        Add(11);
        Add(8);
        Add(12);
        Add(18);
    }
}

Here's what the application looks like:

image

Simple, but I guess you get the idea.

And finally, is it bad to use a web-based API for charting in a desktop application? Not really, in my opinion. Most desktop apps need to talk to servers anyway, and grabbing a few charts over the web is not going to be a significant performance issue.

Oh, one more thing. Of course this works great in Silverlight 2.0 as well.

Wednesday, February 20, 2008

A rating control in XAML

For a pet project I've been working on in WPF I needed a control that would let the user provide a rating between 0 and 5, for example like the one in iTunes and on numerous web sites:

image

After googling a bit I found some samples, including this one posted by Zhou Yong on msdn forums.

However, there was some issues with the functionality (how it reacts to clicks when you click a star that is already lit) and the visuals (the starts themselves and some other minor issues relating to sizing and scaling) so I decided to touch it up a bit. The end result looks like this:

image

It (like the original) is based on toggle buttons with a new template to redo the visuals. It quite nicely illustrates the power of templates in WPF, and what can be achieved just with a little bit of code in a user control. The template looks like this:

   1: <ControlTemplate x:Key="starTemplate"  TargetType="{x:Type ToggleButton}">
   2:     <Viewbox>
   3:         <Path Name="star" Fill="Gray" Data="F1 M 145.637,174.227L 127.619,110.39L 180.809,70.7577L 114.528,68.1664L 93.2725,5.33333L 70.3262,67.569L 4,68.3681L 56.0988,109.423L 36.3629,172.75L 91.508,135.888L 145.637,174.227 Z"/>
   4:     </Viewbox>
   5:     <ControlTemplate.Triggers>
   6:         <Trigger Property="IsChecked" Value="True">
   7:             <Setter TargetName="star" Property="Fill" Value="White"/>
   8:         </Trigger>
   9:     </ControlTemplate.Triggers>
  10: </ControlTemplate>

When working on this I realized how hard it is to find coordinates for a star. The ones I ended up using were lifted from a blog post by Jaime Rodriguez. They are a little bit crooked, but they were the best I could find.

 

Of course the whole control should ideally be implemented as a custom control so that it properly supports styles and templating, but I'll leave that exercise for later.

The code for this sample can be downloaded from here.

Saturday, December 22, 2007

Creating more SQL Server 2005 date functions

TSQL is great, but there's a couple of date-related functions I almost always miss when I'm working with it, at least if I'm doing something related to reporting and BI. Many things need to be displayed per week or quarter, and especially weeks is something that SQL Server isn't very good at. DATEPART doesn't work correctly outside of the US when it comes to week/ww/wk -parts, because it doesn't support ISO 8601 correctly. Years ago I implemented a correct week function as a stored procedure, but now I wanted to do the same in C# in a user defined function and run it through SQL CRL integration.

The first problem I ran into was that the .net Framework claims to implement ISO 8601, but doesn't. Doh! I blogged about this in my last post, "GetWeekOfYear is not reliable in .NET". But with the help of a good post by Shawn Steele I was able to implement a working version.

Creating a user defined function in SQL Server 2005

In Visual Studio there's a project template called "SQL Server Project" that let's you create user defined functions among other things.

image

Once you've created a project based on that template (and specified a database connection) you can right-click on the project node in the Solution Explorer and select "Add" and then "User Defined Function...". Give it a filename (for example "MyDateFunctions.cs"), and click "Add". This gives you a sample function that in at least Visual Studio 2008 looks like this:

   1: using System;
   2: using System.Data;
   3: using System.Data.SqlClient;
   4: using System.Data.SqlTypes;
   5: using Microsoft.SqlServer.Server;
   6:  
   7: public partial class UserDefinedFunctions
   8: {
   9:     [Microsoft.SqlServer.Server.SqlFunction]
  10:     public static SqlString Function1()
  11:     {
  12:         // Put your code here
  13:         return new SqlString("Hello");
  14:     }
  15: };

If you now right-click on the project node in the Solution Explorer and click "Deploy" the code will be compiled, and the function will be deployed to the SQL Server and the database you specified in the database connection you provided when you created the project. If you then open the SQL Server Management Studio (or SQL Server Management Studio Express if you're using that) you can call the function in a query, for example like this: SELECT dbo.Function1()

   1: SELECT dbo.Function1()

Which should return "Hello".

Now, to do something more productive with this, here's the code for two date-related functions:

   1: using System;
   2: using System.Data;
   3: using System.Data.SqlClient;
   4: using System.Data.SqlTypes;
   5: using Microsoft.SqlServer.Server;
   6: using System.Globalization;
   7:  
   8: public partial class UserDefinedFunctions
   9: {
  10:     [Microsoft.SqlServer.Server.SqlFunction]
  11:     public static SqlInt32 Week(SqlDateTime date)
  12:     {
  13:         return new SqlInt32(GetIso8601WeekOfYear(date.Value));
  14:     }
  15:  
  16:     [Microsoft.SqlServer.Server.SqlFunction]
  17:     public static SqlString YearWeek(SqlDateTime date)
  18:     {
  19:         int weekNumber = GetIso8601WeekOfYear(date.Value);
  20:  
  21:         int year = date.Value.Year;
  22:  
  23:         if (weekNumber >= 53 && date.Value.Month == 1)
  24:             year -= 1;
  25:  
  26:         if (weekNumber == 1 && date.Value.Month == 12)
  27:             year += 1;
  28:  
  29:         string yearWeek = year.ToString() + '-' + string.Format("{0:D2}" ,weekNumber);
  30:  
  31:         return new SqlString(yearWeek);
  32:     }
  33:  
  34:  
  35:     // The code below was taken from Shawn Steele's blog post:
  36:     // http://blogs.msdn.com/shawnste/archive/2006/01/24/iso-8601-week-of-year-format-in-microsoft-net.aspx
  37:  
  38:     // This presumes that weeks start with Monday.
  39:     // Week 1 is the 1st week of the year with a Thursday in it.
  40:     private static int GetIso8601WeekOfYear(DateTime time)
  41:     {
  42:         // Need a calendar.  Culture's irrelevent since we specify start day of week
  43:         Calendar cal = CultureInfo.InvariantCulture.Calendar;
  44:  
  45:         // Seriously cheat.  If its Monday, Tuesday or Wednesday, then it'll 
  46:         // be the same week# as whatever Thursday, Friday or Saturday are,
  47:         // and we always get those right
  48:         DayOfWeek day = cal.GetDayOfWeek(time);
  49:         if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
  50:         {
  51:             time = time.AddDays(3);
  52:         }
  53:  
  54:         // Return the week of our adjusted day
  55:         return cal.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
  56:     }
  57: };

The first function, Week, returns the week number for a give date. The second function, YearWeek, returns a string in the format of CCYY-WW, for example "2007-51" for today. This is quite convenient when creating reports and graphs where stuff is grouped per week, because sorting and grouping on such a value is easy.

Once the code above is deployed to the server you can run queries like these:

   1: SELECT dbo.Week('2007-12-31')
   2: SELECT dbo.YearWeek('2007-12-22')
   3: SELECT dbo.YearWeek('2008-2-14')
   4: SELECT dbo.YearWeek('2007-12-31')
   5: SELECT dbo.YearWeek('2008-12-31')
   6: SELECT dbo.YearWeek('2009-12-31')

Which should give you the following result:

   1: 1
   2: 2007-51
   3: 2008-07
   4: 2008-01
   5: 2009-01
   6: 2009-53

So as you can see it gives the right week numbers for the last days of 2007, 2008 and 2009, which DATEPART can't do. In addition, if you use YearWeek, you get a nicely formatted string that you can use in reports and such.

GetWeekOfYear is not reliable in .NET

Microsoft doesn't know what week it is. Or at least they can't calculate it correctly. There's a nice standard, ISO 8601, for how to represent date and time. The Calendar and GregorianCalendar classes implement GetWeekOfYear incorectly, and return the incorrect week for some dates. For example, I realized that they claim that the week number for the date 2007-12-31 is 53, when in fact it is 1. After googling this for a while I found a great post from Shawn Steele that explains how to get around the behavior. Quote:

"A simple workaround to consistently get the ISO 8601 week is to realize that consecutive days Monday through Sunday in ISO 8601 weeks all have the same week #.  So Monday has the same week # as Thursday.  Since Thursday is the critical day for determining when the week starts each year my solution is to add 3 days if the day is Monday, Tuesday or Wednesday.  The adjusted days are still in the same week, and use values that GetWeekOfYear and ISO 8601 agree on."

He also posted a great code sample for this.

I ran into this while creating some date-related SQL CLR functions for use in SQL Server 2005. I'll post more about this is a while.

Update: I blogged some more about this, including sample code and how to use this stuff to create a set of date-related user defined functions in SQL Server 2005 in the post "Creating more SQL Server 2005 date functions".