Sunday, October 18, 2015

NuGet and JavaScript libraries are a bad marriage

Almost everyone who is using Visual Studio uses NuGet today. Its a powerful package manager for .NET based applications. It clearly does it job for maintaining and distribution of libraries. Its also widely used in Enterprise environments where companies setup their own NuGet servers for better application live cycle management of their code.

Well nothing but love... until you try to use NuGet for JavaScript libraries. JavaScript libraries are referenced differently than .NET libraries in Visual Studio projects. .NET libraries are always referenced in the project file, this results in a single list of referenced libraries and the NuGet package manager can always keep track of the downloaded libraries. JavaScript libraries however get dumped in a Scripts folder. Well I don't know about you guys but I easily use 10-20+ JavaScript libraries in a single Web application. So here is the pain in the ass. I'm frustrated about the fact that I can't structure my JavaScript in a more folder like structure. If I move the JavaScript libraries in a different folder than NuGet loses its track of the JavaScript libraries and as a result version upgrades or removal of libraries result in additional or unintentional left files. This problem gets even bigger when you use Typescript. With TypeScript the amount of files for a JavaScript library are almost alwayst doubled since you have to get the definition files. A lot of the most common libraries also contain a bunch of CSS. The exact same problem also applies on CSS, in fact it applies of every non .NET library.

Well thats enough hating, its time for some advise. I think NuGet should introduce a mapping scheme for non .NET libraries. You should be able to place the content of a NuGet package wherever you like in your project. NuGet then should remember those locations and keep track of those files. NuGet should also update their saved locations when a user moves those files. This will be huge for the usability of non .NET libraries in NuGet.

Thank you for reading and please share your thoughts.

Friday, September 4, 2015

Why MCSD certification is important

Recently I have started getting my MCSD Web Applications certification. As a .NET consultant this is quite important from a market value perspective however in my opinion it’s even more important from a personal development perspective.

Let me elaborate, as your company is trying to sell your expertise to a third party it’s important for the third party that they get an employee with the appropriate skills, in my case .NET framework skills. There is always a certain chance that the consultant exaggerates his skills and that he claims to be an expert on certain aspects while he only used the technology for a short amount of time or that he used it in a limited way. For instance, the .NET framework is a really big framework and stating to be expert in it might mean something else for you than for the hiring company. It’s a matter of perception. This resolves in a risk for the hiring company. This risk can be reduced by getting the right certifications. Certifications can’t be misinterpreted since the content of the examinations is fixed. So when the consultant has for instance a 70-487: Developing ASP.net MVC Web Applications certificate you can be sure that he has the appropriate knowledge to build a solid MVC Web application. This certainty reduces the risk of hiring an incompetent employees, which increases the market value of the consultant since hiring an employee with certifications has a higher change of success.

Secondly the personal development perspective. As a, not necessarily Microsoft, software developer you have to keep learning and keep expanding your knowledge. Software languages develop, frameworks expand, new libraries come and go, you simple can't learn one language or one framework and do your thing for 40 years. You need to keep track of new trends and developments. MCSD Certification helps to keep your Microsoft knowledge up to date. Since certifications expire you will have to keep track of new trends and developments or catch up when you retake your examination. The certification functions as a big stick to keep your knowledge up to date. Some developers think that just working experience is enough. I tend to think that that's not true. Working experience is often limited to the technology that applies to the application you are developing. Its pretty hard to keep your MVC knowledge up to date if you are for instance developing a Web Forms application for your work. You will have to catch up in your spare time and MVC is only a small part of the MCSD Web Applications stack. MCSD certifications basically force you to keep track of developments, some guys need it some guys don't. I like it.

Wednesday, February 18, 2015

Async Cordova Windows plugin

Recently I had to write a Cordova plugin for Windows Phone 8.1 and the Windows RT and desktop environment. I went to the Cordova plugin documentation and was disappointed by the lack of information. Hopefully this blog post will help you out.

So I assume that you know a little bit about a Cordova plugin structure. Please take a detailed look at existing plugins when you don't. One important part of a plugin are its platforms. Note that Windows and WP8 are two different platforms. Windows will apply on Windows Phone 8.1 and Windows RT/Metro while the WP8 platform will only apply on Windows Phone 8. This is because the Windows platform generates an Universal App which can be applied on almost every Microsoft Windows runtime.

Every plugin has a plugin.xml which contains information about the files of the plugin. Note that the example below is a stripped version of a plugin.xml file. Every plugin.xml should contain 1 or more platform elements with the supported platforms. Make sure that you create a separate xml element for every platform (ios, android, wp8, windows, etc).

<plugin id="com.foo.bar"
        version="1.0.0"
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns="http://apache.org/cordova/ns/plugins/1.0">
    <name>FooBar</name>
    <platform name="windows">  
        <framework custom="true" src="src/windows/FooBar.dll"></framework>

        <js-module name="WebSqlProxy" src="src/windows/FooBarProxy.js">
            <runs />
        </js-module>
    </platform>
</plugin>

You can specify additional files inside the platform element. These files will be loaded into your application or executed in the Cordova.js context. The framework elements are files that will be added to your application and usually contain native libraries, for Windows usually DLL or WINMD files. WINMD files are commonly used for Windows Phone projects.

Next to the native library files there are JavaScript files inside the js-module elements. There are two kind of JavaScript files that you want to add, namely the proxy JavaScript files and functional JavaScript files. The proxy JavaScript files are used to build a bridge between your native library calls and the JavaScript calls. The functional JavaScript files on the other hand are commonly used to initialize the JavaScript or for example extend the window object with a certain namespace.

Inside element inside the js-module element states the mode of the execution of the JavaScript file. There are several options available but the two major ones are <runs \>, which just executes the JavaScript file and <merges target="x"> which gives you the power to merge a JavaScript object with a certain JavaScript object, such as window.

So there's the plugin.xml. So lets get back to those native libaries. I told you that the Windows platform generates a Universal App. The native library of your plugin should also be a library for Universal Apps. You can create one using Visual Studio > New Project > Templates > Store Apps > Universal Apps -> Windows Runtime Component project. Please choose your name carefully because your namspace is very important. I will use Nimrod.FooBar as namespace in my example.

using System;

namespace Nimrod
{
    // This class must be sealed because Cordova only recognizes sealed classes.
    public sealed class FooBar
    {
        public static string Echo(string value)
        {
            return value;
        }
    }
}

Compile the project and look for the WINMD file. This file should be added to the src\windows plugin directory. Also add it to the plugin.xml as a framework file. After that you can write a JavaScript proxy. It will look like this:

module.exports = {
    echo: function(success, fail, args) {
        var value = args.shift();
        var res = Nimrod.FooBar.echo(value);
        if (res != undefined) {
            success(res);
        } else {
            fail();
        }
    };
};
require("cordova/exec/proxy").add("Nimrod", module.exports);

The module.exports object is extended with an echo function. This function has a call to the native library; Nimrod.FooBar.echo(value). Please note that this syntax is confirm the Namespace.Class.Method syntax used in the native library. The Cordova proxy will map this JavaScript call to the native library.

So how do you use the plugin in your code? Well note that the module.exports is added with Nimrod as key. This will result in a Nimrod object on the window object. So use can use the plugin like this:

// This is a Cordova event that states that all plugins are loaded.
document.addEventListener("deviceready", function () {
    // window.Nimrod doesn't exist in iOS or Android.
    if(window.Nimrod) {
        window.Nimrod.echo(
            function(res) {
                console.log(res);
            }, function () {
                console.log("Something went wrong");
            }, 
            "Hello world"
        );
    }
});

So this is great isn't it? Well not exactly. What if my native library does a time consuming action, such as a database call or a mathematical calculation? My App will be blocked for the entire call. This is because the plugin isn't setup asynchronously. So lets fix that.

The .NET framework has excellent support for asynchronous programming. Especially .NET 4.5 or higher. Please take a look at this example:

using System;
using System.Threading.Tasks;
using Windows.Foundation;

namespace Nimrod
{
    // This class must be sealed because Cordova only recognizes sealed classes.
    public sealed class FooBar
    {
        public static IAsyncOperation Echo(string value)
        {
            return FooBar.doSomeTimeConsumingThings(value).AsAsyncOperation();
        }

        private static async Task doSomeTimeConsumingThings(string value)
        {
            string result = null;
            
            await Task.Run(() =>
            {
                Task.Delay(1000);

                result = value;
            });

            return result;
        }
    }
}

The echo method now returns an IAsyncOperation instead of the string. This AsyncOperation has as effect on the return value in the JavaScript proxy. Instead of being the string value it now will be an JavaScript promise. This will not be blocking the JavaScript. Take a look at the updated proxy code:

module.exports = {
    echo: function(success, fail, args) {
        var value = args.shift();
        var promise = Nimrod.FooBar.echo(value);
        promise.done(function (res) {
            success(res);
        });
        promise.fail(function () {
            fail();
        });
    };
};
require("cordova/exec/proxy").add("Nimrod", module.exports);

I hope this helped, if you have any questions feel free to ask. I might be able to help you out any further.

Thursday, February 5, 2015

Combo breaker reloaded

In March 2014 I wrote a blog post about some issues I ran into while developing an HTML5 App using Cordova and JQuery Mobile for Windows 8. Well it has been 10 months and I would like to share some additional solutions to those problems. Especially the "dynamic content" and "usage of unsafe HTML" issues.

As you probably know, jQuery Mobile uses AJAX navigation to switch between pages. This creates a richer user experience but also causes some issues on the Windows platform(both metro and phone). Your page might contain some unsafe HTML which will cause the following error:

Unhandled exception at line 5472, column 5 in ms-appx://<app identifier>/www/js/jquery/jquery-2.0.2.js

0x800c001c - JavaScript runtime error: Unable to add dynamic content. A script attempted to inject dynamic content, or elements previously modified dynamically, that might be unsafe. For example, using the innerHTML property to add script or malformed HTML will generate this exception. Use the toStaticHTML method to filter dynamic content, or explicitly create elements and attributes with a method such as createElement.  For more information, see http://go.microsoft.com/fwlink/?LinkID=247104.

If there is a handler for this exception, the program may be safely continued.

In the previous blog post I created a hack in jQuery with a MSApp.execUnsafeLocalfunction wrapper which allows adding dynamic content. Well this hack was highly volatile and probably incomplete. Luckily for you and me we have some smart guys at MSOpenTech which solved this problem for us. They created a "JavaScript Dynamic Content shim for Windows Store apps".

The shim basically wraps all unsafe properties and functions in a MSApp.execUnsafeLocalfunction call. This will prevent WinJS from throwing exceptions when you dynamically add unsafe HTML. Please take a look at their Github page for more information.

Hope this helps!

Friday, November 28, 2014

HTML5 Canvas Game

Recently I've been working on a simple HTML5 canvas game. I came up with the idea after browsing through some arcade games that I used to play. One of them was Tyrian2000, its a classic space game where you have to destroy as many enemies as possible. After playing it for a while I thought it might be cool to create a game like that with a Star Trek theme. I recently watched Star Trek Enterpise(new series) so that subject was still fresh in my memory.

I created a simple TypeScript project and played with the canvas element a little bit. Everything worked out pretty well and after a short amount of time I created a space ship which could fly in a rolling space background. I tested everything on Internet Explorer and Chrome and had no problems at all, so I went on. After that I tried to run it inside a Cordova App and came to a shocking conclusion. The canvas performance is absolutely horrible in Android. I have a Nexus 10 tablet which runs on Android 5.0 and the canvas fps was super slow.

As I was determined to continue I started to research the problem on the Internet. Unfortunately it didn't get better. I found some solutions and performance tip and tricks but they didn't seem to workout miracles. The conclusion: use C++ for Mobile Game development. The hardware acceleration on the canvas element is very bad on mobile devices and your game will probably don't perform well on it. So sadly I had to quit my quest for a Mobile game on HTML5 canvas, but I'm determined to continue. I'm currently researching some C++ game environments/libraries. I'm currently looking into: Cocos 2D and Marmalade

Thursday, October 9, 2014

DB2 calling a stored procedure in a loop

Hi there folks, it has been a while, my apologies. I recently started some database work on SQL Server and DB2. I had some difficulties with DB2 since I have very few experience with it. I tried to execute a stored procedure in a loop. I managed to do it on SQL Server using a cursor but the lack of documentation for DB2 exacerbates the problem. I hope to help the internet with some code examples, feel free to use them.

SQL Server:
DB2:

Wednesday, March 26, 2014

Combo breaker: Cordova + JQM + Windows8

This blog post is about issues you probably come across while you're creating a Windows 8.1(not phone) hybrid app with Cordova. First of all let me set some context variables. I use Cordova 3.4, jQuery Mobile 1.4.0, jQuery 2.0.2 and i'm creating a Windows 8.1 app for a desktop or tablet environment. I've already created the app for Android 2.3 or higher, and iOS 6 or higher.

I'll try to explain the whole process step by step. If you have any questions feel free to reply.

1. Update Cordova and its plugins
If you want to support Windows 8 you have to update to the newest version of Cordova. You can simply update Cordova using the following commands:
> npm update -g cordova
Or if you want a specific version:
> npm update -g cordova@3.4.0
Update the plugins after you've updated Cordova. Just re-add the plugins and they will be updated to the newest version. For more information please visit the Cordova manual.

2. Add Windows 8 platform
Add the Windows 8 platform to your Cordova project. Use the following command:
> cordova add platform windows8
3. Try building your project
Use the Visual Studio Command prompt(VS2012 x64 Cross Tools Command Prompt) to build a Windows 8 platform. This is needed because Cordova uses Visual Studio's build tools to create your Windows 8 app.
> cordova build windows8
4. Try running your App
Open your solution in Visual Studio after you've build with Cordova. Try to run your App on your Local Machine. You might get some JavaScript errors but that depends on whether or not you've added a platform to an existing project. In my case, I've already created an App with thousands of lines of JavaScript. That JavaScript needs to be compatible with the new Internet Explorer and WinJS environment. You probaly run into some issues, this is what I ran into:

Usage of unsafe HTML elements and attributes.
HTML thats get injected into your page needs to be filtered by the toStaticHTML method. This method sanitizes your HTML and strips all unsafe elements and attributes. The list of unsafe elements and attributes can be found here. Does this mean that you can't inject an image element with a source attribute? No it doesn't, you can add it but you can't inject strings with unsanitized HTML. You should add HTML elements with unsafe elements in the following way:

/* Old way */
h1Element.prepend("<img src='someUrl.png' />");
/* New way */
var img = document.createElement("img");
img.className = "icon";
img.src = "someUrl.png"
h1Element.prepend(img);

Invalid use of dynamic content using jQuery Mobile.
One of the most difficult problems is the dynamic content issue that is caused by jQuery Mobile. jQuery Mobile uses AJAX navigation to switch between pages, this means that the content of the new page is injected in the old page. Therefore you don't have to add all JavaScript references to all pages. This works great, however it causes the following issue in Windows 8:

Unhandled exception at line 5472, column 5 in ms-appx://<app identifier>/www/js/jquery/jquery-2.0.2.js

0x800c001c - JavaScript runtime error: Unable to add dynamic content. A script attempted to inject dynamic content, or elements previously modified dynamically, that might be unsafe. For example, using the innerHTML property to add script or malformed HTML will generate this exception. Use the toStaticHTML method to filter dynamic content, or explicitly create elements and attributes with a method such as createElement.  For more information, see http://go.microsoft.com/fwlink/?LinkID=247104.

If there is a handler for this exception, the program may be safely continued.

The exception is thrown on the appendChild of jQuery. appendChild adds the HTML from the new page to the old page. However, the new page contains, in my case, some unsafe HTML. I use for attributes on label elements. This causes the error because the for attribute is considered unsafe. I haven't found a solid fix yet and therefore I present my workaround.

You can add unsafe HTML in WinJS but you have to wrap the call in a MSApp.execUnsafeLocalFunction. This will prevent WinJS from throwing an error when unsafe HTML gets added to the DOM. Unfortunately appendChild isn't the only place that throws errors when jQuery Mobile switches between pages that contain unsafe HTML. You should wrap the domManip function in a execUnsafeLocalFunction. Look at the following code:

// Check if the userAgent is Microsoft Internet Explorer
// This doesn't work in Internet Explorer but only in Windows 8 (Metro) apps.
if (/MSIE/.test(navigator.userAgent)) {
    // Cache the old domManip function.
    jQuery.fn.oldDomManIp = jQuery.fn.domManip;
    // Override the domManip function with a call to the cached domManip function wrapped in a MSapp.execUnsafeLocalFunction call.
    jQuery.fn.domManip = function (args, callback, allowIntersection) {
        var that = this;
        return MSApp.execUnsafeLocalFunction(function () {
            return that.oldDomManIp(args, callback, allowIntersection);
        });
    };
}

Invalid objects XML Document.
My App which handles large amounts of business data uses SOAP to communicate with the back-end. The XML response from the back-end is without any conversion used a data source in the App. The XML gets stored in a so called reader object which can extract the rows and columns from the XML, this worked fine until Windows 8 came around the corner.

The XML documents become invalid after a certain amount of time. You can't do anything about it, even caching the requests or documents them self don't solve the problem, it only delays the problem. All calls to a XML document that has become invalid throw an "Invalid calling object" error.

One solution to this problem is converting your XML document to JavaScript Objects. This may hurt your performance but the lifetime of JavaScript objects is in your hand and not in Microsoft's.

5. Test App
You have to test your App if you want to upload it to the Windows Store. This test can be done after you've created the app package. A package can be created by: right-clicking on your project > Store > Create App Packages. After the package is created Windows will prompt you with  a dialog to start the Windows App Certification Kit. Run all tests and see if the test fails. Don't interact with your system while the kit is running its tests. It may influence the test results, yes I tried it :) And grab a cup of coffee because it takes several minutes...

My App failed because the encoding of the JavaScript and CSS files were incorrect. They need to be UTF-8 encoded. I searched the web for a simple PowerShell script to encode the files correctly, and modified the script to be recursive and look for CSS and JavaScript files.

Make sure that you run the PowerShell script in the platform\windows8 folder. It will screw up your project if you run it in the project folder. Here is the script:

Get-ChildItem .\* -include *.js,*.css -Recurse | ForEach-Object {
    $content = $_ | Get-Content
    Set-Content -PassThru $_.Fullname $content -Encoding UTF8 -Force
}

6. Deploy the App
With the build comes a PowerShell script to deploy your App locally. Note that this script installs the certificate that is selected in the appxmanifest. This can be a security risk, since you probably don't store your key in a (Software) vault. The PowerShell script can be found in the AppPackages folder in the Visual Studio's project folder.

I haven't deployed my App to the Windows Store yet. I'll add a description to this blogpost when I have.

References: