Porting .NET Code To Windows 8 Style

Porting .NET code to Windows 8 Style (Windows Store App) can take more time you think of. The libraries in the framework are different. Based on a sample I will show you some of that differences and how it can affect your application design beside of the XAML UI things.

AVM FRITZ!Box Sample Code

In the sample code below I’m requesting FRITZ!Box device information.

I think the code from them contains some very illustrative material for the topic, because Crypt-Api and Basic HTTP communication is included.

You will find the technical specification here. (in German): AVM FRITZ!Box – Communicate with the device using Session ID (HTTP).

http://www.avm.de/de/News/artikel/schnittstellen_und_entwicklungen.php

The original code can be found in this document

http://www.avm.de/de/Extern/files/session_id/AVM_Technical_Note_-_Session_ID.pdf

GetMD5Hash

A crypto method to get a MD5 hash.

Original

        public string GetMD5Hash(string input)
        {
            MD5 md5Hasher = MD5.Create();
            byte[] data = md5Hasher.ComputeHash(Encoding.Unicode.GetBytes(input));
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                sb.Append(data[i].ToString("x2"));
            }
            return sb.ToString();
        }<

Windows 8 Style

        public static string GetMD5Hash(string str)
        {
            var alg = HashAlgorithmProvider.OpenAlgorithm("MD5");
            IBuffer buff = CryptographicBuffer.ConvertStringToBinary(str, BinaryStringEncoding.Utf16LE);
            var hashed = alg.HashData(buff);
            var res = CryptographicBuffer.EncodeToHexString(hashed);
            return res;
        }

As you can see here there is no equal line of code!

GetChallenge

A method to get the first part of a security token (challenge)

Orignal

public string GetChallenge()
{
XDocument doc = XDocument.Load(@"http://fritz.box/cgi-bin/webcm?getpage=../html/login_sid.xml");
XElement info = doc.FirstNode as XElement;
return info.Element("Challenge").Value;
}

Windows 8 Style

The code is equal

GetSID

A method to get a secure authenticated Session ID needed to request password secured FRITZ!Box information.

Original

        public string GetSid(string challenge, string response)
        {
            HttpWebRequest request = WebRequest.Create(@"http://fritz.box/cgi-bin/webcm") as HttpWebRequest;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            string parameter = String.Format(@"login:command/response={0}-{1}&amp;getpage=../html/login_sid.xml", challenge, response);
            byte[] bytes = Encoding.ASCII.GetBytes(parameter);
            request.ContentLength = bytes.Length;
            Stream stream = request.GetRequestStream();
            stream.Write(bytes, 0, bytes.Length);
            stream.Close();
            HttpWebResponse wr = request.GetResponse() as HttpWebResponse;
            StreamReader reader = new StreamReader(wr.GetResponseStream());
            string str = reader.ReadToEnd();
            XDocument doc = XDocument.Parse(str);
            XElement info = doc.FirstNode as XElement;
            return info.Element("SID").Value;
        }

Windows 8 Style

/// <summary>
/// Because the method MUST be implemented asyncronous in Windows 8
/// the async keyword is required
/// </summary>
public async Task<string> GetSidAsync(string challenge, string response)
{
string parameter = String.Format(@"login:command/response={0}-{1}&getpage=../html/login_sid.xml", challenge, response);

// there is no ASCII encoder in Windows 8, but you can use UTF8 instead
byte[] bytes = Encoding.UTF8.GetBytes(parameter);

// instead of using HTTPWebRequest you should use HTTPClient
ByteArrayContent content = new ByteArrayContent(bytes);

content.Headers.Add("Content-Length", bytes.Length.ToString());
content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");

HttpClient client = new HttpClient();
var responseMsg = await client.PostAsync(@"http://fritz.box/cgi-bin/webcm", content);
var str = await responseMsg.Content.ReadAsStringAsync();
XDocument doc = XDocument.Parse(str);
XElement info = doc.FirstNode as XElement;
return info.Element("SID").Value;
}

As you can see nearly everything is different. Why? The main reason is, because Windows 8 requires an async programming model. With the help of the new async and await keywords it is easy and very straight forward. Also the HTTPWebRequest is a bit outdated and should be replaced with HTTPClient together with the use of HTTPContent classes. The main interesting point for me is the that the lines of code is less than the original version – async and await are amazing.

SeiteEinlesen (ReadPage)

Original version of SeiteEinlesen (ReadPage)

        public string SeiteEinlesen(string url)
        {
            Uri uri = new Uri(url);
            HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
            HttpWebResponse response = request.GetResponse() as HttpWebResponse;
            StreamReader reader = new StreamReader(response.GetResponseStream());
            string str = reader.ReadToEnd();
            return str;
        }

Windows 8 Style

public async Task<string> SeiteEinlesenAsync(string url)
{
Uri uri = new Uri(url);
var client = new HttpClient();
var resp = await client.GetAsync(uri);
var str = await resp.Content.ReadAsStringAsync();
return str;
}

The differences are the same as in GetSID method.

Conclusion

Porting a .NET desktop application to Window Store App can put you on trial. As you can see in the code from above, the differences can be substantial for the whole application design also because asynchronous method invocation is required. It is not just switching the UI to Windows 8 Style XAML. When starting a porting project a first step can be to create a prototype containing all technical aspects of your application. This could help you to build a roadmap.

Advertisements
Tagged , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: