Archive for category Coding

JavaScript for Metro-style apps: now I get it.

I’ve spent the last few days at the Microsoft //build/ conference where the first preview version of Windows 8 was shown (and everyone got a tablet PC, which I like, and – and this is going to be important for the rest of the post – has built-in 3G network).

I really quite like the new Metro-style UI for touch applications. I’ve liked the Metro UX framework from the start when it first came into view on Windows Phone 7. I’m not sure if it’s a good idea to go to the full-screen home screen for launching apps when in desktop mode, but that’s a different story, and you can still install Launchy anyway.

What I didn’t really understand was why JavaScript and HTML were integrated into the platform in such a deep way. You have three independent language systems for creating applications that use the new Windows Runtime (“WinRT”): native C++ code with XAML as markup, .NET with XAML as markup, and JavaScript with HTML as markup. Each of them is anchored into the system at the same level. Access to the WinRT is provided to each of these systems in a different way using “projections”: translations of type systems and conventions to make working with the WinRT feel like you did not. Repeat; JavaScript has been anchored AT THE SAME LEVEL AS C++ AND .NET.

Phase 1: Writing it off

Seeing actual code written in HTML/JS however was quite a downer. I had hoped for a more semantic way of expressing layout than XAML provides. XAML is basically a 1-to-1 representation of an object graph, while HTML expresses layout more as an intent. I normally find working with XAML a lot less productive than it should be. However, to make use of the controls that the platform provides, you need to drop concrete class names into your markup, making HTML for Metro-style applications more concrete than it should be.

As for JavaScript, there is an extra JavaScript library called the WinJS to provide access to platform specifics. And there are some: since an HTML application is, well, and application instead of a web site, it needs to care about process lifecycle and state management. It’s really hard to put this in words – do you know the feeling when something looks all reasonable, but just does not feel right? That’s it with me and the WinJS.

But my main problem with the whole HTML/JS stack was that I could not understand WHY. Everyone I talked to stated that the HTML path for building Metro-style apps existed so that web developers could bring their existing skill set and write great apps from the get-go. I don”t quite buy this. Because first of all, an existing skill set might not be so important. The enormous success of the iOS platform proves that if something is attractive enough, you even write Objective-C. I think it’s an underestimation of developers who master modern web site development when you assume they could not learn some C# or VB on a level that makes you perfectly productive at the level you need for UI programming.

And secondly, you actually have to extend your skill set anyway: WinRT controls, WinJS, process lifecycle management…

So what I concluded is that the HTML/JS stack was basically an oversized technological approach to solve the business problem that for the platform to succeed, it’ll have to launch with a fully stacked app store.

Phase 2: and then I got it.

I have two days left in California before I head back to Germany. I’m going to take a shower, pack my things, and drive south to the beach once this blog post is finished. Which will cause me my favorite problem: I tend to get lost. And the car does not have GPS.

But what I do have is a tablet PC with GPS and a 3G connection. So when I woke up at 4AM (the jet lag never left), I sat down and wrote myself a Metro app that displays a map full screen, and puts my current position into the center, and puts a pin at it.

And how do you display a Google Map? Yeah. Exactly. All you need is some HTML and JS. (I ended up using Bing Maps because it works better with the pinch-to-zoom gesture).

Here’s the app.

The thing that sets apart the HTML/JS way of writing Metro-style apps over using XAML markup is not that it’s easier to write, or yields better results. In fact, I believe that for larger apps, the robust type system and patterns like MVVM give .NET a clear edge.

HTML/JS Applications that integrate with web resources intensely have a lot less friction. You don”t need to write an adapting SDK to translate between a service like Maps. HTML and JavsScript are the native language of the web, and when you go there, it’s better to speak that language well.

, ,

3 Comments

Beware of the dreaded passive arbiter!

The setup seemed simple enough: Two application servers running ASP.NET MVC, and a MongoDB replica set with two standard nodes and an arbiter.

If you’re familiar with MongoDB replica sets, feel free to skip the following paragraph:
When using MongoDB in a productive environment, two servers and an arbiter is much of the absolute minimum requirement. You cannot seriously run on a single server; MongoDB is not designed to provide good durability on just one machine. A two-node replica set provides replication of changes to a second machine. It also provides a failover server should one server go down. A replica set works much like classic master-slave replication, but the master is elected automatically: if the node that currently holds the master role (the “primary”) does not respond to a heartbeat, another node (a “secondary”) becomes the new primary. Which secondary is promoted is quite an interesting ceremony. An important aspect is that for a primary to be elected, it needs to “see” the majority of nodes in the replica set – otherwise, a broken network link could split the replica set in the middle, and there’d be two primarys (see a popular piece of fantasy literature on what happens in such a situation). A result of these rules is that a replica set with just two nodes cannot work – when one server goes down, the other won’t see a majority; even when the secondary node fails, the primary demotes itself because it finds itself alone.
This is where an arbiter comes in. An arbiter is a MongoDB instance that does not hald any data. It does not take part in replication. Its sole purpose is to provide a majority for the election of a new primary. In a two-node setup with an arbiter, one server can fail and the other still has a majority of two thirds of the replica set.
And then there’s priority. Priority is a MongoDB server setting that determines the order in which nodes are elected primary – a node with a higher priority wins. The most useful setting for priority however is 0. Setting a node’s priority to 0 makes it a “passive” node – it will never become elected the primary. This is useful if a machine is e.g. used just for backups, or if it’s in a remote data center. Otherwise, a passive node acts like a normal member of the replica set – data is replicated to it, and it can be used for running queries against it.

Alright. So we’ve got passive nodes, and arbiters. This is mutual exclusive – an arbiter cannot be a passive node. Passive nodes can be used for queries, arbiters can’t, they don’t hold data.

To query the status of a node in a replica set, you can run the command db.isMaster() against it. It returns a document that describes the shape of the replica set, and the role the queried server plays within it. Two fields that are returned are if the node is a passive, and if it’s an arbiter.

The C# driver for MongoDB (and probably other drivers as well) use the isMaster command to determine which servers are available, which is the primary, and qhich ones can be used for queries. If a query is allowed to be executed against a read-only replica of the database by setting the slaveOk setting, the driver looks for secondary and passive nodes. Which is correct. But this is where things start to go wrong – using this sequence of in itself harmless details.

MongoDB up to and including the current version 1.81 allow setting the priority on an arbiter node.

If you set the priority to 0, a node will report itself to be a passive. Yes, this includes arbiters. Ouch.

The driver looks for secondaries and passives to run queries. It does not exclude arbiters, because these normally aren’t secondaries or passives. Except when the server claims to be one, because someone set the priority to 0. Second ouch.

If you run a query against an arbiter, it will return an error that it’s neither primary nor secondary, and cannot be read from: { "$err" : "not master or secondary, can't read", "code" : 13436 } .Luckily, the driver recognizes the connection as faulty and removes it from the connection pool.

So what kept me busy for about ten working hours was this: an application server was reporting a MongoDB error once every time the IIS application pool had restarted. It turned out it was connecting to an arbiter, and the reason for that was that a DBA had set the priority on the sorry arbiter to 0, which was a leftover of its configuration before it became an arbiter.

First conclusion: don’t set the arbiter’s priority to 0. Just don’t. Arbiters don’t need a priority setting, or in fact, mostly no settings at all.

Second conclusion: I really love MongoDB for its simplicity, the data modelling possibilities, and its performance. But things like the dreaded passive arbiter really raise a question mark on its maturity – the problem would have been easily avoidable on either the server or the driver (or both, for better). What also needs to be admitted that 10gen is extremely responsive and helpful. They promised to fix the C# driver within a week(!) in release 1.2, and scheduled a fix for the server for version 1.92 – all within one day reaction time.

, ,

Leave a Comment

C# Enum Quirks

I’ve been slashing out C# code since 2000. Just today I discovered something totally new to me.

Would you reckon that this test is valid?

public enum Direction
{
	Left,
	Right 
}

[TestClass]
public class EnumQuirks
{
	[TestMethod]
	public void Cast_any_number_to_enum()
	{
		Direction direction = (Direction)5;
		Assert.AreEqual(5, (int)direction);
	}
}

In fact, it is. An enumeration can be casted to its underlying data type, of course; by default, this is an Int32. What I hadn’t realized is that the conversion works the other way too. Any integer value can be assigned to an enum, whether the values are defined or not. In order to safely assign a numeric value, the result of Enum.IsDefined can be evaluated.

But it gets weirder. In order to convert a string value into an enum, there’s the TryParse method. But when it tries parsing really hard, look what it can do:

[TestMethod]
public void TryParse_accepts_any_number_in_string()
{
	string value = "5";
	Direction direction;
	bool canParse = Enum.TryParse(value, out direction);
	Assert.AreEqual(5, (int)direction);
	Assert.IsTrue(canParse);
}

This is even documented:

Enum.TryParse: Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.

It converts the numeric value too. And since there is no check if there is a constant defined for any numeric value, any string that can be parsed to a number is valid.

Lesson learned: you can’t trust assignments to enumerations without checking Enum.IsDefined. And if there’s code out there that parses string coming from an insecure source (like an web request), you can’t rely on Enum.TryParse.

Leave a Comment

MongoDB: when documents aren’t perfect, cope with it

MongoDB is a NoSQL database that organizes data as JSON documents in collections instead as rows in tables. One major difference between a document in a collection and a row in a table is that while all rows in a table share the same schema, each document in a collection can be completely different. With all the huge advantages this approach brings, there is a friction when strongly typed domain objects are deserialized from a collection. A document needs to match the shape of the object that it should be serialized to.

The “official” MongoDB driver for .NET – that is the one offered and supported by 10Gen, the company behind MongoDB – offers a serializer that can be told quite exactly how tolerant it needs to be with the deserialization of JSON documents in to objects:

  • When a JSON document defines extra elements that are not present in the class that it is deserialized into, the serializer can either ignore them, stash them into a “catch-all” property, or throw an exception.
  • When properties on the class are missing in the JSON document, the serializer can set the property to null, it can set a default value, or it can throw an exception.

These options are well described in the official documentation.

Handling deserialization errors in collections

The Mongo C# driver supports operations to retrieve single elements from the database as well as collections. As we’ve seen, there is a lot of flexibility in defining a level of tolerance that matches your application’s requirements for the deserialization of single objects, the policy for collections is very simple: if any element fails, the whole collection is not loaded. While this is the right behaviour for scenarios that rely on data integrity, applications that focus on availability are threatened by complete loss of functionality when just a single document in a collection does not match the deserialization requirements.

  • A scenario that relies on data integrity is a form in a line of business application that edits a list of closely related data like line items of an invoice. The line items all need to provide the same set of information, otherwise the invoice cannot reliably be calculated.
  • A scenario that focuses on availability is a search in a product catalogue in an online shop. If a single product is not correctly formatted in the database, it’s better to just not show that single product than letting the whole search page become unavailable and basically close the shop until the ill-formatted product is identified and corrected.

In the case of the search page, a better behaviour would be to exclude any document that cannot be serialized, and provide a callback that identifies the problematic documents. The approach I’ve taken is to copy the default implementation of the collection serializer, and augment the bit that iterates over the elements of the collection with an event handler that keeps the iteration running:

while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
{
	var elementType = discriminatorConvention.GetActualType(bsonReader, typeof(T));
	var serializer = BsonSerializer.LookupSerializer(elementType);

	T element;
	try
	{
		element = (T)serializer.Deserialize(bsonReader, typeof(T), elementType, null);
		list.Add(element);
	}
	catch (FileFormatException exc)
	{
		// Pass the exception to the provided callback
		if (HandleDeserializationError != null)
		{                           
			HandleDeserializationError(exc);
		}

		// Move the cursor to the next element after the faulted one
		while (bsonReader.State != BsonReaderState.EndOfDocument)
		{
			if (bsonReader.State == BsonReaderState.Value) bsonReader.SkipValue();
			if (bsonReader.State == BsonReaderState.Type) bsonReader.ReadBsonType();
		}
		bsonReader.ReadEndDocument();
	}                    
}
bsonReader.ReadEndArray();

You can download the full source from Bitbucket. Please note that it’s not production quality – it has not been used in production, but that could change over the next few weeks, and then it’s going to get an update with the real thing.

1 Comment

Fixing non-localizable validation messages with JavaScript

There is a nasty globalization bug in ASP.NET MVC: the client-side validation message for numeric is hard coded to a string that is not localizable.

Take the following view model class:

public class SomeViewModel
{
    public int SomeNumber { get; set; }
}

… and this view:

@model SomeViewModel
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
    Html.EnableClientValidation();
    Html.EnableUnobtrusiveJavaScript();
}
@using (Html.BeginForm())
{    
    @Html.EditorFor(vm => vm.SomeNumber)
    @Html.ValidationMessageFor(vm => vm.SomeNumber)
}

If the user enters a non-numeric value into the text box form SomeNumber, client side validation kicks in and displays a message. This is excellent, you can’t have validation for less effort. This message is “The field SomeNumber must be a number.”. Umm. That might need some rewording, especially when you wish to translate the user interface into a language other than English. The trouble is: you can’t.

The string “The field {0} must be a number.” is baked into ASP.NET MVC in a resource file. There is no way to define a different resource file, or overwrite the message in any other way (like there is for server-side default messages by setting DefaultModelBinder.ResourceClassKey). For other messages, like the message for required fields, this is not a big deal because a custom message can be applied by setting a DataAnnotation attribute – however, this is not possible for data type based validation.

The options at hand are:

  • Do without the integration of data types and client side validation, and not use EditorFor. Instead, declare the text box directly, and set the data-val-number attribute that controls the message directly. Yuck – that feels like gearing the progeamming model around a platform bug. I’m not desperate for that yet.
  • Fix ASP.NET MVC. It’s open sourced, you can run your own fixed branch, or at least replace the part that causes the problem. Yes, I might do this, but it causes some maintenance problem – each time a new version of the framework is released without a fix, I’d need to recompile. Sounds like a lot of work.
  • Use AOP to basically do the same. That solutions yields a lot less code, but still has a very tight dependency on the current version of the framework; in addition, I’d need to throw another framework into the project. Maybe.
  • The problem lies within ASP.NET MVC, but in the outcome, it’s just a client-side message. Hence, replacing the non-localized message with a localized one does not have to happen on the server. Let’s see where these messages are applied!

The validation rules and messages for client side validation are defined in HTML5-style “data-” attributes that are attached to the form’s input elements. As an example, this is what ASP.NET emits for the integer value from the example above:

 <input 
	class="text-box single-line" 
	data-val="true" 
	data-val-number="The field SomeNumber must be a number." 
	data-val-required="The SomeNumber field is required." 
	id="SomeNumber" 
	name="SomeNumber"
	type="text"
	value="0" />

There are two JavaScript modules that construct the client side validation:

  • jquery.validate provides all the heavy lifting for evaluating and comparing values, and for displaying the messages.
  • jquery.validate.unobstrusive hooks the validation functionality provided by jquery.validate into the page in an “unobstrusive” way – that is, without any JavaScript code that clutters the page. Instead, attributes on the validated controls declare what should be validated.

When jquery.validate.unobstrusive is loaded, it reads all validation attributes on the current page. This is the first chance to change the content of the attribute. The script is cleverly structured; it attaches a host of adapters that match attributes and then initialize the appropriate jquery.validate function. A set of options is passed through the adapter, containing (among other things) the message. Directly after jquery.validate.unobstrusive is loaded, we can hook into its adapters and change the one for numbers:

(function ($) {
    // Walk through the adapters that connect unobstrusive validation to jQuery.validate.
    // Look for all adapters that perform number validation
    $.each($.validator.unobtrusive.adapters, function () {
        if (this.name === "number") {
            // Get the method called by the adapter, and replace it with one 
            // that changes the message to the jQuery.validate default message
            // that can be globalized. If that string contains a {0} placeholder, 
            // it is replaced by the field name.
            var baseAdapt = this.adapt;
            this.adapt = function (options) {
                var fieldName = new RegExp("The field (.+) must be a number").exec(options.message)[1];
                options.message = $.validator.format($.validator.messages.number, fieldName);
                baseAdapt(options);
            };
        }
    });
} (jQuery));

Now, instead of the message defined by ASP.NET MVC, the default message provided by jQuery.validate is used. This is much better because this one _can_ be localized:

$.validate.messages.number="Eine Nummer für {0}, bitteschön";

Instead of inventing your own messages you should maybe use the jquery-glob plugin that comes with a variety of langauges.

Using this solution in your own project

  1. Copy the JavaScript code above into a new JavaScript file named jquery.validate.unobstrusive.fixMvcNumberMessage.js in the Scripts directory of your ASP.NET MVC project.
  2. Add a reference to that file directly beneath jquery.validate.unobstrusive. The references to scripts are normally held in the _Layout shared view.

Feel free to use the code in this article as it serves you.

, ,

3 Comments

NUnit for Silverlight: Runs on Windows Phone 7, too

Yesterday I’ve hauled the “big” laptop home from work and tried plugging the unofficial port of the NUnit unit testing framework for Silverlight into Windows Phone 7. Jeff Wilcox had added support for Windows Phone 7 into his Silverlight unit test framework bis from last May already, so it’s little surprise that there was not much of a problem.

I did not compile the whole of the NUnit port to the Windows Phone 7 runtime, but use the Silverlight 3 version that references the May 2010 unit testing framework. When these assemblies are referenced, Visual Studio complains that using a Silverlight assembly could lead to unpredictable behavior, but this does not apply to this project. Firstly, the major differences are really close to the user interface, and NUnit does not render anything anywhere, it does not even reference anything Silverlight-specific types. Secondly, the whole test suite runs without errors. Compiling the NUnit framework to the WP7 runtime would be totally feasible, but any test project on WP7 needs to reference the Silverlight unit testing framework, which is a Silverlight 3 assembly. You’ll get the warnings about unpredictable behavior anyway.

The documentation on ho to run NUnit tests on Windows Phone 7 is on the Coogle Code Wiki. The project’s binaries have not changed, but I’ve added a version of the NUnit test suite for Wp7 that you can find in the code.

, ,

Leave a Comment

Link whole directories into Visual Studio Projects

You can include a file into a Visual Studio project in two ways: copy it into the project directory, or link it. Copying the file into the project directory is Visual Studio’s default option: it’s what happens when you drag a file from Explorer into VS’s project explorer, or when you use the dialog Project -> Add existing item. This is fine unless you wish to share files between multiple projects. An example where I needed to share a whole lot of files between different projects is NUnit for Silverlight: the same code is used by three projects for different versions of Silverlight and the Silverlight unit testing framework.

To link a file into Visual Studio, you can use the Project -> Add existing item dialog: the “Add” button has a dropdown menu, and the second option is “Add as link”. This will leave the file where it is and add a relative link to the Visual Studio project file. In the project file (which is BTW a MSBuild file), this looks like that:

    <Compile Include="..\..\..\src\VersionInfo.cs">
      <Link>VersionInfo.cs</Link>
    </Compile>

If you add multiple files, Visual Studio will create one item like this for each file. To add all files in a directory, mark all files in the the Project -> Add existing item dialog, and link them. This is fine as long as you don’t delete any files or add new ones – Visual Studio will not pick up these changes. New files in the directory won’t be in the project, and deleting/renaming files will cause the build to fail.

A solution is to modify the project file manually. The Include directive supports wildcards. So to link all C# code files in a directory, you can do this:

   <Compile Include="..\..\..\src\NUnit.Silverlight.Framework\*.cs" />

Nice, but in the case of NUnit for Silverlight, there were C# code files in subdirectories. Using the Compile directive as above, the files are included, but all appear in the root folder of the project – and if a file with the same name exists in the parent directory and the subdirectory, it won’t work. However, there is support for metadata keywords in MSBuild. For example, the %(Filename) keyword is a placeholder for each match in a wildcard. See this article for reference: MSBuild: By Example—Introducing Well-Known Metadata. Now we can include subdirectories:

 <Compile Include="..\..\..\src\NUnit.Silverlight.Framework\*.cs" />
    <Compile Include="..\..\..\src\NUnit.Silverlight.Framework\Attributes\*.cs">
      <Link>Attributes\%(FileName)</Link>
    </Compile> 
	<Compile Include="..\..\..\src\NUnit.Silverlight.Framework\Constraints\*.cs">
      <Link>Constraints\%(FileName)</Link>
    </Compile> 
    <Compile Include="..\..\..\src\NUnit.Silverlight.Framework\Exceptions\*.cs">
      <Link>Exceptions\%(FileName)</Link>
    </Compile> 

As you see, I need to link three subdirectories. Using a * placeholder in the directory name and the %(RecursiveDir) keyword should enable adding these with a single statement like this:

 
    <Compile Include="..\..\..\src\NUnit.Silverlight.Framework\*\*.cs">
      <Link>%(RecursiveDir)%(FileName)</Link>
    </Compile> 

… but that does not work. Never mind, including subdirectories one by one is enough for me right now.

4 Comments

NUnit for Silverlight 2.5.8

Finally, another drop of NUnit test framework for Silvelight has been finished:

  • It is based on NUnit version 2.5.8, a step up from 2.5.5.
  • The complied assemblies are strong-named. I’ve included the key in the source code so that if you want to compile yourself, you’ve got the exact same version.
  • The project is now hosted on Google Code. I’ve removed the links to download the sources and binaries from Dropbox.
  • I reviewed the licenses to see what the license for the complete oevre could be. The answer is that there are in fact two licenses: NUnit has its own license; the source code contains the terms. This license applies to the Nunit.Silverlight.Framework and Nunit.Silverlight.Framework.Tests assemblies. The metadata provider for the Silverlight unit testing framework goes back to Jeff Wilcox, who has put this piece under MS-PL. So the MS-PL applies to the NUnit.Silverlight.Metadata assembly.
  • In the test runner, data tests now have names that reflect the parameter values, and are available for the original version of the unit testing framework for Silverlight 3.

The next thing to come will be support for Windows Phone 7.

Download

Please download from nunit-silverlight on Google Code.

,

Leave a Comment

Silverlight is a failed attempt (of sorts)

As someone living in the Microsoft client programming world, it’s very hard not to get emotionally drawn into the Silverlight vs. HTML5 discussion in the aftermath of the PDC 2010. And so do I.

Silverlight is a failed attempt, and HTML5 is completely taking over its role.

I think the above statement is true for at least one of the original drivers behind the product. Silverlight was announced and marketed as an alternative to Flash for video playback and streaming. Silverlight version 1 could hardly do anything other – that probably means that powerful stakeholders had pushed the video capabilities of the platform to a higher priority than most anything else. If I had to guess the business driver I’d say I’d say they wanted their piece of the Youtube business model – ad-supported video delivery. Flash was at the time the only medium capable of delivering against that goal, so Microsoft put a lot of effort into making Silverlight the better video player. Just look at all the work they’ve put into codecs, DRM, and streaming. They went public with streaming the 2008 Olympics – you can’t really launch any bigger.
Well, that plan did not really fly so well. Silverlight could not become dominant over Flash, and now Flash is being driven out of the market – by the means of adding video playback capabilities directly into the browser. So in conclusion, Silverlight is a complete fail in what the people who pay for it regarded its primary use case.

Even with version 2, Microsoft’s vision for Silverlight was much more about media and gaming than about larger-scale applications. Again, this story is hardly a tale of triumph. Everyone was extremely excited when Linerider was ported to Silverlight, but that was kind of a solitary success (and the productive version is still in Flash).

For line of business application with a rich UI, Microsoft’s proposition was a WPF application with Click-Once-Deployment. The success of Silverlight as a platform for internal business applications seemed to come as a surprise, and some effort has been put into making the platform better suited for that purpose since.

So when Microsoft now announces they’re adjusting the vision and strategy for Silverlight, you could also read that of a confession of previous failure.

,

2 Comments

Updated: Syntax Highlighting for ScrewTurn Wiki

ScrewTurn Wiki is an excellent free wiki engine that I love and that I’ve written a source code syntax highlighter plugin for.

The plugin literally just hooks in the client-side SyntaxHighlighter by Alex Gorbatchev. Alex has published a new version some months ago. The version 3 has better support for copy&paste without the need for buttons in the toolbar, and some added elegance in its internal structure and extensibility. The new version of the plugin simply uses this version; there’s not much else to be said about it.

If you’re using the ScrewTurn wiki plugin with your own downloaded version of the SyntaxHighlighter, it’d be best to update to version 3 as well. You can use ScrewTurn’s auto-update functionality to obtain the new version of the plugin.

Links

,

3 Comments

Follow

Get every new post delivered to your Inbox.