Navigation Bar issues between iOS 6 and iOS 7

A major difference between iOS 6 and 7 is that in iOS 7 the navigation bar is translucent by default and stuff appears underneath it instead of being shifted down.

Normally this is fixed by making the navigation bar opaque, but this doesn’t always work. An additional solution is described here, and translated to Xamarin it is:

using MonoTouch.ObjCRuntime;

...

public override void ViewDidLoad ()
{
    base.ViewDidLoad ();
    if (RespondsToSelector(new Selector("edgesForExtendedLayout")))
    {
        EdgesForExtendedLayout = UIRectEdge.None;
    }
...
}

Using XmlReader.Read() with ReadElementContentAs*()

Most samples of using an XmlReader use a Read in a while loop like this:

var value1 = 0;
var value2 = 0;
var value3 = 0;
while (reader.Read())
{
    if(reader.IsStartElement())
    {
        switch(reader.Name)
        {
            case "Element1":
                value1 = reader.ReadElementContentAsInt();
                break;
            case "Element2":
                value2 = reader.ReadElementContentAsInt();
                break;
             case "Element3":
                value3++;
                break;
         }
    }
}

However, this pattern may fail if elements are not separated by whitespace. The culprits are the ReadElementContentAs* methods. Without separating whitespace they leave the reader at the start of the next element. The Read at the top of the loop moves it past this next start element and it will be skipped completely.

This is particularly nasty because it works well with nicely formatted XML, which you’ll probably use while testing, because it has whitespace between elements. However, dense XML generated by a feeding system will trip it up.

Instead you can use something like this:

var value1 = 0;
var value2 = 0;
var value3 = 0;
while (!reader.EOF)
{
    if(reader.IsStartElement())
    {
        switch(reader.Name)
        {
            case "Element1":
                value1 = reader.ReadElementContentAsInt();
                continue;
            case "Element2":
                value2 = reader.ReadElementContentAsInt();
                continue;
            case "Element3":
                value3++;
                break;
        }
    }
    reader.Read();
}

The Read at the top of the loop is replaced by an EOF check and moved to the bottom. This allows skipping it with the continue keyword after using a ReadElementContentAs* method or anything else that leaves the reader at the start of the next element. Anything else is followed by a break to move the reader forward.

Please note the use of continue instead of break is rather subtle so a comment is probably in order.

BTW, if you want to test XML documents without having to edit terse XML files load pretty formatted XML in an XDocument and then open an XmlReader from it. Apparently this reads the XML without the whitespace nodes.

Booting an SD Card

I’m running out of USB sticks with all the Windows and Linux images I like to try out. However, I still have a bunch of SD cards left. Both my laptops have an SD card slot but unfortunately they cannot boot from it.

Recently I bought a USB connected multi-card reader and after some experimentation I succeeded in booting from an SD card inserted in the reader. Sweet!

Unfortunately the Windows 7 Download Tool created an invalid image, resulting in a boot error. It is however possible to make the SD card bootable manually. After copying all files from a Windows 7/8 ISO you can boot from it.

Linux images created with pendrivelinux worked perfectly.

I have only tried it with this USB multi-card reader, so your mileage may vary.

So now I finally have some use for those old SD cards!

Secure RESTful WCF Service with SHA-256 hashing

This is an old draft I found, perhaps it is useful if you’re trying to do SHA-256. If not, let me know, I might be able to help you out.

Azure Storage supports secure access of resources without logon. It involves hashing the query part of the URL and then signing that hash. I’ve implemented this at my workplace in the following steps:

  • Create a web project for a WCF service.
  • Update the .svc file by adding (this makes everything work without configuration, found this here):

Factory=”System.ServiceModel.Activation.WebServiceHostFactory”

  • Add the following attribute to your interface method:

[WebInvoke(Method = "GET", BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "?p0={parameter0}&p1={parameter1}&sig={signature}")]

  • Create a method like (please note that parameter names match those specified in the WebInvoke attribute and that they are all string type):

Stream MyMethod(string parameter0, string parameter1, string signature);

  • In the implementation of MyMethod verify the signature with the following function:

bool ValidSignature(string customerID, string signature, paramsstring[] toSignArguments)
{
    var certificate = FindCertificate(customerID);
    if (certificate == null)
{
        return false;
}
    const string TERMINATOR = “\n”;
    var toSign = string.Join(TERMINATOR, toSignArguments) + TERMINATOR;
    var oldProvider = (RSACryptoServiceProvider)certificate.PublicKey.Key;
    using (var newProvider = new RSACryptoServiceProvider())
{
newProvider.ImportCspBlob(oldProvider.ExportCspBlob(
false));
        return newProvider.VerifyData(Encoding.UTF8.GetBytes(toSign), “SHA256″, Convert.FromBase64String(signature));
}
}

The trick is to create a new provider instead of the default one you get when loading the key. The default is connected to the wrong library that doesn’t support SHA-256.

Installing latest nginx on lubuntu

I finally managed to install the latest nginx on my test lubuntu install after following this link and some of my own fumbling. The default repositories are several versions behind. Don’t expect this to work on your system, it’s more of an inspiration. I sudo’ed each command but a single su would have been quicker on hindsight.

sudo apt-get autoupdate
sudo aptitude install python-software-properties
sudo add-apt-repository ppa:nginx/stable
sudo aptitude update
sudo apt-get install nginx

URL Trailing Slash: subtle difference between Web API and WCF Rest

Just found an interesting difference between Web API and WCF Rest when you supply a URL with a trailing slash, e.g. http://server/path/1/.

Say you have a Web API deployed to server with a PathController. This will catch a URL with or without a trailing slash, so http://server/path/1 and http://server/path/1/ are equivalent.

On the other hand, assume you have a WCF Rest service deployed at server with a service contract containing a method decorated with [WebGet(UriTemplate="path/{id}")]. This will listen to http://server/service.svc/path/1 but http://server/service.svc/1/ will return an HTTP status code 404 with a message endpoint not found.

If the method is decorated with a trailing slash like [WebGet(UriTemplate="path/{id}/")] the service will listen to http://server/service.svc/path/1/. Trying to invoke it without the trailing slash like http://server/service.svc/path/1 will return an HTTP response code 307 Temporary Redirect with the equivalent location but including a trailing slash.

I now hope this won’t bite you as much as it bit me ;-).

Get SID of user account with PowerShell

I was looking at this post that uses a bit of C# code to get the SID of a user account. A Powershell Script however is easier to run:

(new-object System.Security.Principal.NTAccount('DefaultAppPool')).Translate([System.Security.Principal.SecurityIdentifier]).Value

Then replace ‘DefaultAppPool’ with the account you want the SID of. Note that the square brackets [...]s are like typeof(…) in C# while they’re also used to do a cast.