Front-end Development in dotnet.sg

yeoman-bower-npm-gulp

The web development team in my office at Changi Airport is a rather small team. We have one designer, one UI/UX expert, and one front-end developer. Sometimes, when there are many projects happening at the same time, I will also work on the front-end tasks with the front-end developer.

In the dotnet.sg project, I have chance to work on front-end part too. Well, currently I am the only one who actively contribute to the dotnet.sg website anyway. =)

Screen Shot 2017-01-29 at 12.49.23 AM.png
Official website for Singapore .NET Developers Community: http://dotnet.sg

Tools

Unlike the projects I have in work, dotnet.sg project allows me to choose to work with tools that I’d like to explore and tools that helps me work more efficiently. Currently, for the front-end of dotnet.sg, I am using the following tools, i.e.

  • npm;
  • Yeoman;
  • Bower;
  • Gulp.

Getting Started

I am building the dotnet.sg website, which is an ASP .NET Core web app, on Mac with Visual Studio Code. Hence, before I work on the project, I have to download NodeJs to get npm. The npm is a package manager that helps to install tools like Yeoman, Bower, and Gulp.

After these tools are installed, I proceed to get a started template for my ASP .NET Core web app using Yeoman. Bower will then follow up immediately to install the required dependencies in the web project.

screen-shot-2017-01-28-at-9-03-10-pm
Starting a new ASP .NET Core project with Yeoman and Bower.

From Bower with bower.json…

Working on the dotnet.sg project helps me to explore more. Bower is one of the new things that I learnt in this project.

To develop a website, I normally make use of several common JS and CSS libraries, such as jQuery, jQuery UI, Bootstrap, Font Awesome, and so on. With so many libraries to manage, things could be quite messed up. This is where Bower comes to help.

Bower helps me to manage the 3rd party resources, such as Javascript libraries and frameworks, without the need to locate the script files for each resources myself.

For example, we can do a search of a library we want to use using Bower.

Screen Shot 2017-01-28 at 9.44.47 PM.png
Search the Font Awesome library in Bower.

To install the library, for example Font Awesome in this case, then with just one command, we can easily do it.

$ bower install fontawesome

The libraries will be installed in the directory as specified in the Bower Configuration file, .bowerrc. By default, the libraries will be located at the lib folder in wwwroot.

screen-shot-2017-01-28-at-10-08-44-pm
Downloaded libraries will be kept in wwwroot/lib as specified in .bowerrc.

Finally, to check the available versions of a library, simply use the following command to find out more about the library.

$ bower info fontawesome

I like Bower because checking bower.json into the source control ensures that every developer in the team has exactly the same code. On top of that, Bower also allows us to lock the libraries to a specific version. This will thus prevent some developers to download some different version of the same library from different sources themselves.

…to npm with package.json

So, now some of you may wonder, why are we using Bower when we have npm?

Currently, there are also developers supporting the act to stop using Bower and switch to npm. Libraries such as jQuery, jQuery UI, and Font Awesome, can be found on npm too. So, why do I still talk about Bower so much?

Screen Shot 2017-01-28 at 11.30.58 PM.png
Searching for packages in npm.

For ASP .NET Core project, I face a problem on referring to node_module from the View. Similar as Bower, npm will position the downloaded packages in a local folder also. The folder turns out to be node_module, which is on the same level as wwwroot folder in the project directory.

As ASP .NET Core serves the CSS, JS, and other static files from the wwwroot folder which doesn’t have node_module in it, the libraries downloaded from npm cannot be loaded. One way will be using Gulp Task but that one is too troublesome for my projects so I choose not to go that way.

Please share with me how to do it with npm in an easier way than with Bower, if you know any. Thanks!

Goodbye, Gulp

I first learnt Gulp was when Riza introduced it one year ago in .NET Developers Community Singapore meetup. He was then talking about the tooling in ASP .NET Core 1.0 projects.

Riza Talking about Gulp.png
Riza is sharing knowledge about Gulp during dotnet.sg meetup in Feb 2016.

However, about four months after the meetup, I came to a video on Channel9 announcing that the team removed Gulp from the default ASP .NET template. I’m okay with this change because using BundleMinifier to do bundling and minifying of CSS and JS now without using Gulp because using bundleconfig.json in BundleMinifier seems to be straightforward.

Screen Shot 2017-01-28 at 11.59.18 PM.png
Discussion on Channel 9 about the removal of Gulp in Jun 2016.

However, the SCSS compilation is something I don’t know how to do it without using Gulp (Please tell me if you know a better way. Thanks!).

To add back Gulp to my ASP .NET Core project, I do the following four steps.

  1. Create a package.json with only the two compulsory properties, i.e. name and version (Do this step only when package.json does not exist in the project directory);
  2. $ npm install --save-dev gulp
  3. $ npm install --save-dev gulp-sass
  4. Setup the generated gulp.js file as shown below.
var gulp = require('gulp');
var sass = require('gulp-sass');

gulp.task('compile-scss', function(){
    gulp.src('wwwroot/sass/**/*.scss')
        .pipe(sass().on('error', sass.logError))
        .pipe(gulp.dest('wwwroot/css/'));
})

//Watch task
gulp.task('default', function() {
    gulp.watch('wwwroot/sass/**/*.scss', ['compile-scss']);
})

After that, I just need to execute the following command to run gulp and changes made to the .scss files in the sass directory will trigger the Gulp Task to compile the SCSS to corresponding CSS.

$ gulp

There is also a very detailed online tutorial written by Ryan Christiani, the Head Instructor and Development Lead at HackerYou, explaining each step above.

Oh ya, in case you are wondering what is the difference between –save and –save-dev in the npm commands above, I like how it is summarized on Stack Overflow by Tuong Le, as shown below.

  • –save-dev is used to save the package for development purpose. Example: unit tests, minification.
  • –save is used to save the package required for the application to run.

Conclusion

I once heard people saying that web developers were the cheap labour in software development industry because they are still having the mindset that web developers just plug-and-play modules on WordPress.

After working on the dotnet.sg project and helping out in front-end development at work, I realize that web development is not an easy plug-and-play job at all.

Picking Up SCSS

sass-web-compiler-visual-studio-pluralsight

Last week, during our work discussion, we came to this point where we argued if “fast first, slow later” or “slow first, fast later” is suitable in our working environment.

In startup mode, everything comes at you quickly, and you tend to react fast. So in the first two years of setting up the Innovation Team in Changi Airport, our software development team had been working very hard and very fast to meet the deadline. Now, our company is switching from startup mode to scale-up mode where we need to shift towards doing things right more often than doing things fast.

Hence, we are working on setting up a set of suitable development and design principles in our development team. Applying SCSS to refactor our CSS is part of this time-consuming, difficult, and tiring process.

Installing Web Debugger in VS2015

After the introduce of Web Essentials 2015, features such as compiling SCSS files have been moved to another extension called Web Compiler in Visual Studio.

Hence, to get started in VS2015, we need to first download Web Compiler via Tools > Extensions and Updates.

Installing Extensions in VS2015.png
Installed Web Compiler in Visual Studio 2015

We will need to restart Visual Studio after the installation. Once the Visual Studio is restarted, we then can start using SCSS in our web projects.

By using Web Compiler, every time we save the .scss file, it will auto compile it to be a corresponding .css file (with minified version as well!).

Another feature that I like in this extension is that Visual Studio will specify whether the SCSS files are “Compiled successfully” or there is any SCSS error, as shown in the screenshot below.

SCSS Error Reporting in VS2015.png
Visual Studio will provide friendly error messages for SCSS too!

Refactor CSS into SCSS

Previously, besides using CSS from Bootstrap, we mostly handcrafted our CSS. Recently, it had become quite hard to maintain. So I started to refactor the CSS files from one of our web projects into SCSS.

Firstly, I created a new set of blank SCSS files while keeping the existing CSS files untouched. Secondly, I change the CSS reference of the website to use the new CSS files generated by the Sass pre-compiler. By doing this, I can choose to slowly refactor the existing CSS.

Change I Love #1: Introduction of Variables

Taking just brand colour as an example, currently our CSS files have it all over the place. The same shade of blue appears a lot of times. It is incredibly hard and time consuming to make changes in our web projects using plain CSS.

Previously, for example, we have the following CSS.

.btn-main {
    background-color: #28c8f0;
    border-color: #28c8f0;
}

The primary colour #28c8f0 is used in other classes throughout the whole CSS. Hence, we can just define it as a variable $primary-color: #28c8f0; and then use it

.btn-main {
    background-color: $primary-color;
    border-color: $primary-color;
}

In the future, if we want to change the primary colour to another colour, we just need to change it at one place without worrying if we miss out any part of the CSS not updated.

Change I Love #2: DRY with Mixin

Don’t Repeat Yourself (DRY), if we are using plain CSS, we normally find ourselves reusing the same set of codes throughout the CSS files. So, by using mixins in SCSS, there will always be one and only one set we need to remember and reuse.

Before using SCSS:

.customized-width-250 {
    margin-top: 4px;
    border: 1px solid #ffffff;
    border-radius: 5px 5px 5px 5px;
    font-weight: bold;
    height: 30px;
    min-width: 250px; 
}

.customized-width-120 {
    margin-top: 4px;
    border: 1px solid #ffffff;
    border-radius: 5px 5px 5px 5px;
    font-weight: bold;
    height: 30px;
    min-width: 120px; 
}

.customized-width-60 {
    margin-top: 4px;
    border: 1px solid #ffffff;
    border-radius: 5px 5px 5px 5px;
    font-weight: bold;
    height: 30px;
    min-width: 60px; 
}

Now, by using mixin, we can easily remove the duplicates for easy maintenance.

@mixin customized-controls ($width) {
    margin-top: 4px; 
    border: 1px solid #ffffff; 
    border-radius: 5px 5px 5px 5px; 
    font-weight: bold; 
    height: 30px;
    min-width: $width;
}

.customized-width-250 {
    @include customized-controls(250px);
}

.customized-width-120 {
    @include customized-controls(120px);
}

.customized-width-60 {
    @include customized-controls(60px);
}

Change I Love #3: Loops and Conditional

On our website, we need to display representative image for each of the countries available on the portal.

If we are using plain CSS, we need to do the following for each country. For example, for Australia, we have the follows.

.country-box-australia {
    background-image: url("/images/device-country-australia.png");
}

Now we have 9 countries on our portal. So we need to repeat the lines above for 9 times. If the images are moved to another folder, then we need to update the CSS at 9 places.

In SCSS, we can use list and each loop to make the CSS more readable.

$portal-countries: australia, france, hong-kong, japan, malaysia, new-zealand, south-korea, taiwan, thailand;

@each $country in $portal-countries {
    .country-box-#{$country} {
        background-image: url('/images/device-country-#{$country}.png')
    }
}

As you see above, it also makes use of Interpolation #{} to make the code even cleaner.

Change I Love #4: Color Functions

This is helpful especially when we do the hover effect for buttons. Previously, we always needed to ask the Design Team to give us two colour codes for buttons. One for non-hover and one for hover.

So with the Color Functions in SCSS, we can now do as follows.

a {
    text-decoration: none;
    color: $primary-color;

    &:hover, &:focus {
        text-decoration: none;
        color: darken($primary-color, 20%);
    }
}

We then can have a consistent look-and-feel throughout the whole website.

Oh ya, the & character above is used to reference parent selector.

Change I Love #5: Partials

We can also have partials by starting the name of the partials with an underscore.

Because of partials, we can organize our SCSS files properly according to their functionality.

Conclusion

I believe that now given the fact that our company is already in a scale-up mode, if we keep doing everything in a hacking way, we will easily end up with technical debt soon. Having technical debt means that we will need to spend extra development work in the future because the best overall solution is not implemented in the beginning.

That is why I always welcome opportunities to learn and improve my skills. This includes learning from my teammates via our countless conversations because the conversations kept me inspired and kept me going. The team had made me a better developer. Picking up SCSS is one of the examples and it is only the beginning.

Learning Materials

Nice Report Always Comes with Colourful Charts

Normally, we will show only tabular data in our online report module. However, tables are not exciting. So, why don’t we add some charts to the report to better describe the data? Thanks to Google Charts, web developers can add colourful charts to the web pages easily.

Step 1: The Required Libraries

The first thing we need is the Google API Loader which allows us later to easily load APIs from Google. So, with the help of it, we can make use of the Google Hosted Libraries.

 type="text/javascript" src="https://www.google.com/jsapi">

After that, we will load the API which will help us drawing charts. To do so, we will have the following JavaScript code.

google.load("visualization", "1.1", { packages: ["corechart"] });

Material Design

What is Google Material Design? There is an interesting video from Google Design team sharing the ideas behind it. (Image Credit: Google Design)
What is Google Material Design? There is an interesting video from Google Design team sharing the ideas behind it. (Image Credit: Google Design)

Recently, in order to support a common look-and-feel across all Google properties and apps running on Google platforms, Material Design is introduced to Google Charts as well.

There are more than 20 of charts available in Google Chart Gallery. Depends on which chart that you would like to use, you need to load different API in order to use the Material version of each chart. I played around with some of them which are useful in my use cases.

The first chart that I use is the Column Chart which is to draw vertical bar chart. So, the API can be called as follows.

google.load("visualization", "1.1", { packages: ["bar"] });

Other than vertical bar chart, another common graphs used in report will be Line Chart. The API of Line Chart can be called as follows.

google.load("visualization", "1.1", { packages: ["line"] });
Line Chart is available on Google Charts.
Line Chart is available on Google Charts.

The third chart that I use is Timeline. This chart is different from the two charts introduced above because so far I still can’t find the non-Material version of it. So, the only way to call the API of Timeline is as follows.

google.load("visualization", "1.1", { packages: ["timeline"] });
Timeline is a chart describing the happening events over time.
Timeline is a chart describing the happening events over time.

Step 2: The Data

After we have loaded API of the chart that we want to use, then we need to pump in the data.

var data = new google.visualization.DataTable();
data.addColumn('string', 'Branch');
data.addColumn('number', 'Sales');
data.addRows([
    ['Ang Mo Kio', 1205.80],
    ['Bedok', 828.90],
    ['Clementi', 2222.10],
    ['Dhoby Ghaut', 3180.00]
]);

In the code above, I created a data table with 2 columns. Then I added 4 rows of data with addRows.

The addRows part can be done using a simple for loop. However, due to the fact that not all browsers support Tailing Comma, the for loop needs to have additional step to remove Tailing Comma.

Step 3: Chart Render

After we have the data, now we can proceed to draw the chart. For example, if we want to draw a Column Chart for the data table above, then we will use the following code.

var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));chart.draw(data);

The HTML element chart_div above is just an empty div where the chart should be rendered at.

We will then be able to get the following diagram (Non-Material).

A simple Column Chart.
A simple Column Chart.

Customization of Charts with Options

Google Charts allows us to customize the diagram. For example, we can add title for the diagram, horizontal axis, and vertical axis.

var options = {
    title: 'Sales of Branches',
    hAxis: {
        title: 'Branch'
    },
    vAxis: {
        title: 'Amount (SGD)',
        minValue: 0
    },
    legend: {
        position: 'none'
    }
 };

chart.draw(data, options);

In the code above, I not only added titles, but I also force the vertical axis to start from 0 and hide the legend by setting its position to none.

Column chart is now updated with helpful titles.
Column chart is now updated with helpful titles.

What we have seen so far is the non-Material Column Chart. So how will a Material Column Chart look like?

To get a Material Column Chart, we will change the code above to the following.

var options = {
    chart: {
        title: 'Sales of Branches',
        subtitle: '2015 First Quarter'
    },
    axes: {
        y: { 0: { label: 'Amount (SGD)' } },
        x: { 0: { label: 'Branch' } } 
    },
    legend: {
        position: 'none'
    }
};

var chart = new google.charts.Bar(document.getElementById('chart_div'));

chart.draw(data, options);

Then we will be able to get the Material version of the chart. Now, we are even able to define a subtitle for the diagram.

Yup, we successfully upgraded our chart to the Material version.
Yup, we successfully upgraded our chart to the Material version.

In case you would like convert a non-Material Column Chart to a Material version, you can do so with the code below too.

chart.draw(data, google.charts.Bar.convertOptions(options));

Challenge with Tab in Bootstrap

When I was adding Google Charts to one of my web page with tabs using Bootstrap framework, I realized there was a problem with the display of the rendered diagram. The labels in the chart are incorrectly positioned. This problem has been discussed on Stack Overflow as well.

 

Display Issues of Google Charts in Bootstrap Tabs
Display Issues of Google Charts in Bootstrap Tabs

Interestingly, if the chart happens to be in the first tab which is visible by default, then there won’t be any display issue on the chart. This problem only occurs when the charts are located in those subsequent tabs which are hidden during the first load of the page. When user clicks on any of those subsequent tabs, then the display issue will happen.

So one obvious solution is actually to only call the Google API to render the graph when the tab is clicked. To be safe enough, I actually put a delay to the click event of the tab so that the chart will be drawn 3 seconds after the the corresponding tab is clicked. This seems to help fixing the display problem.

Similar to my solution, there is also a better alternative which is to bind the draw function to the show event of the tab, as discussed on Stack Overflow. I like the solution too because of its cleanliness of the code.

Try More with Google Charts

Google Charts is undoubtedly a very easy-to-use solution for web developers to present their data. So, please try it out and be amazed by the number of charts available on Google Charts.

Summer 2015 Self-Learning Project

This article is part of my Self-Learning in this summer. To read the other topics in this project, please click here to visit the project overview page.

Summer Self-Learning Banner

Modernizr and Progressive Enhancement

Modernizr

Since Visual Studio 2012, we can always find this file called modernizr-(version).js in the default ASP .NET 4.5 MVC template. So, what is Modernizr (can be downloaded from Nuget)?

Modernizr is a JS library which is able to detect HTML5 and CSS features in the user’s browser. During page load, Modernizr will start to test those next-generation features. After that, it will create a JS object which contains the test results. For example, Modernizr.canvas will be true if the browser supports the HTML5 <canvas> element.

Modernizr then adds CSS classes to the <html> tag that tell us which CSS / HTML5 features are supported on the current user’s browser. For example, in my Chrome browser, touch feature is not supported, thus, there is a no-touch class added. The other features like video, audio are all supported.

<html class=" js flexbox flexboxlegacy canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths">

With this information, we will then be able to provide alternative look-and-feel for those users who are using older versions of browser instead of telling those users “Best view in version xxx of browser yyy”.

With YepNope.js, we will also be able to tell Modernizr what to test and then what JS/CSS to load if the test passes or fails.

Finally, please remember that Modernizr only provides us information about which features are (not) supported. It won’t magically enable those features for us. We need to write corresponding JS/CSS to provide alternative views when the features are not supported on the browser.

In short, Modernizr is a good tool for designers to implement the idea of Progressive Enhancement.

Graceful Degradation

When I was reading about Progressive Enhancement, I read this term called Graceful Degradation. It basically means the way of using the newest and best web technologies while maintaining support for older browsers.

The famous border-radius feature in CSS3 is supported in modern browsers like IE11, Edge, Chrome, and Firefox but it’s not supported in Internet Explorer 7 and 8. Does this stop us from using border-radius in our website? Nope. This is because for users who are still using IE7/8, they can still use the website in the same way as those who are using modern browsers. Just that those who are using old browsers cannot see the beautiful effect of border-radius.

Different visual effect in IE8 and IE11.
Different visual effect in IE8 and IE11.

So basically the idea of Graceful Degradation is that it starts at ideal user experience level and it decreases depending on browser capability down to a minimum level.

Progressive Enhancement

Progressive Enhancement does in the opposite way as Graceful Degradation. It starts at a board minimum user experience and increases depending on browser capability. For example, when user switches from old browser to modern browser, he/she will be able to experience more advanced functionality that will be automatically enabled on the modern browser. So, Modernizr helps us to achieve this by checking if a certain feature is enabled or not on the current browser.

References

Summer 2015 Self-Learning Project

This article is part of my Self-Learning in this summer. To read the other topics in this project, please click here to visit the project overview page.

Summer Self-Learning Banner

Journey to ASP .NET MVC 5

When I first worked as web developer after graduation, I used to think what I knew about web development was already enough. However, as I learned more from friends and colleagues, I realized how difficult the field is, even though in Easibook.com we were just dealing with ASP .NET for web development.

New Ideas

Singapore .NET Developers Community meetup
Singapore .NET Developers Community meetup (Photo Credit: .NET Developers Singapore)

I participated in the Singapore .NET Developers Community meetup with my colleagues on 28 January. The theme is about web development. We had the chance to learn about ASP .NET MVC 5, Dependency Injection and how ASP .NET MVC 5 works with Angular JS.

What interested me is the ASP .NET MVC 5 talk given by Nguyen Quy Hy. In work, I was always using ASP .NET Web Forms. When I first started the ASP .NET MVC project in Visual Studio, I was already shocked by new terminologies like Razor, Identity, Scaffold, and all sort of folders, such as Models, Views, Controllers, App_Start, etc. Those are basically not found in my existing Web Forms project.

Working in a startup, there is always more to do and even more to learn, no matter the size of business. In many ways, my job changes frequently. I have to always take time to learn and challenge myself to play with new technology. Hence, learning ASP .NET MVC becomes my new challenge in this year.

I thus decided to write this post to share about what I’ve learned in my ASP .NET MVC 4/5 projects in February.

Bootstrap

Let’s start with simple stuff first. The GUI.

It’s nowadays quite common that people want a website which is responsive and mobile friendly. Luckily, there are frameworks to help. A even better news is that Visual Studio web application template by default is using Bootstrap, a framework providing design and theming features.

Previously we were using VS 2008. There was no such thing as bootstrap in our Web Forms application. Hence, I only started playing with Bootstrap when I did my first ASP .NET MVC 4 project in VS 2012.

ASP .NET web server controls can no longer be seen in ASP .NET MVC project. I was once asked about how GridView and paging were going to be handled in ASP .NET MVC without the use of the web server controls. I found some online discussions and articles which gave good answer to the question.

  1. Grid Controls for ASP .NET MVC
  2. Bootwatch: Free themes for Bootstrap including table and paging themes
  3. Paging, Searching, and Sorting in ASP .NET MVC 5
  4. ASP .NET MVC Paging Done Perfectly with @Html.PagedListPager()

12-Column Grid System is another thing I learnt when playing with Bootstrap. The grid system allows us to easily create complex grid layouts for different devices.

Grid System of Bootstrap 3
Grid System of Bootstrap 3

With the help of Bootstrap, even before I do anything, my web application is already responsive and mobile friendly. It’s true that technology is just a tool but with the right tools, we are able to work more efficiently and productively. =)

Native Support of Clean URL: Good News for SEO

My colleague, who was doing SEO, always received requests to do URL Rewrite in our existing Web Forms applications. Whenever there is a new page created, he has to add a new rule to web.config, sometimes just to get rid of the .aspx thingy.

<urlrewritingnet rewriteOnlyVirtualUrls="true" contextItemsPrefix="QueryString" defaultPage="default.aspx" xmlns="http://www.urlrewriting.net/schemas/config/2006/07">
    <rewrites>
        <add name="RedirectInDomain" virtualUrl="^http\://(.*)/SomethingFriendly"
            rewriteUrlParameter="IncludeQueryStringForRewrite" 
            destinationUrl="~/test.aspx" ignoreCase="true" 
            redirectMode="Permanent" rewrite="Domain" />
        ...
 
     </rewrites>
 </urlrewritingnet>

If there are one thousand pages, then there will be same amount of rules. So in the end, we even need to create separate config file just to keep the rules for URL rewrite.

In ASP .NET MVC 5, with the help of ASP .NET Routing, URLs no need to be mapped to specific web pages. Hence, in MVC web application, we can always see clean URLs which is friendly to not only the web crawler but also sometimes to the users. This is one of the features that I love in ASP .NET MVC.

Identity and Social Network Login

Whenever I visit an online store, I always find it more customer-friendly to accept Facebook or Google login.

Fortunately, ASP .NET Identity is powerful enough to not just accept application-wise user name and password, but also allows the connections from social websites like Facebook, Twitter, and Google+.

I only need to create a Facebook app and then key in the https URL of my website. After that, I put both the application ID and secret key to Startup.Auth.cs. Tada, users can now login to my website with their Facebook credentials.

app.UseFacebookAuthentication(
    appId: "<Facebook app ID here>",
    appSecret: "<Facebook app secret here>");
Localhost HTTPS URL is also accepted! =)
Localhost HTTPS URL is also accepted! =)

Just in case if you also encounter exception saying “Object reference not set to an instance of an object” on the line with AuthenticationManager.GetExternalLoginInfoAsync(), as shown in the following screenshot, please update Microsoft.Owin.Security.Facebook Nuget package.

Facebook Login Exception. Boom!
Facebook Login Exception. Boom!
Update nuget.org - Microsoft.Owin.Security.Facebook
Update nuget.org – Microsoft.Owin.Security.Facebook

Entity Framework Code First

Due to the fact that my project is a new one. So, I used Code First to help me create tables in a new database according to my Model definition.

There is also a video on MSDN Data Developer Center website where they give an introduction to Code First development.

I like how easy it is to have all my tables created auto-magically by just defining model using classes. Then after that, I can create new views and controller by adding Scaffold.

Easily create MVC controller and views with Scafolding
Easily create MVC controller and views with Scafolding

Headache with Migrations

In order to have database scheme updated when the model is changed, I have enabled migration by running the Enable-Migrations command.

Ran Enable-Migrations command in the Package Manager Console
Ran Enable-Migrations command in the Package Manager Console

After that, whenever I changed my model classes, I will run Update-Database to have database schema updated as well. However, soon I encountered a problem.

When I was working on an ASP .NET MVC 4 project with VS2012, the Id in the Users table is integer. So, in VS2013, I assumed it to be the same when I created the model classes and updated the database. Unfortunately, nope. The default web application of VS2013 uses GUID for user ID. There is an online tutorial on how to change the primary key of Users back to integer, if you are interested.

Due to the fact that my project is a totally new project, so what I am going to do is just to change my model classes to use GUID as the type of storing user ID in other tables. However, when I ran the Update-Database command, the console prompted me an error message, saying “Operand type clash: int is incompatible with uniqueidentifier”. To quickly get rid of this problem, I deleted my tables (Don’t do this at home. =P) from the database. Then when I ran Update-Database command again, it complaint the table was missing. Finally, I had no choice but deleting the relevant records in __MigrationHistory table before making Update-Database to work again. =P

Yay, successfully updated database schema after deleting migration history.
Yay, successfully updated database schema after deleting migration history.

Yay with Entity Framework

Before using Entity Framework, I played with stored procedure for few years. My colleagues have always been complaining that sometimes the logic was being hidden in stored procedures and thus made the debugging difficult. Also, having logic in stored procedures means that our business logic is actually split up into both C# and SQL. So, sometimes the developers need to spend a few hours debugging the C# code before realizing the store procedure was actually the culprit.

With Entity Framework, I am now able to modify the table structure and logic all in C# code which helps developers to easily find out where goes wrong.

Still, sometimes it is good to group related functions into one well-defined stored procedure so that the system only needs to call to the database once to get all the work done. However, after reading a 400-line store procedure once, I decided that doing this may not be the best option because no one in my team was interested to debug SQL code.

Review a long stored procedure?
Review a long stored procedure?

There are more related topics online regarding Entity Framework vs. Stored Procedures, as listed below. If you are interested, feel free to check them out.

  1. Entity Framework Vs Stored Procedures – Performance Measure
  2. Stored Procedure or Entities?

Using MySQL Instead of Default SQL Server: I Was Having a Hard Time

By default, the data provider of ASP .NET Identity with Entity Framework is set to be MS SQL in VS 2013. However, MS SQL Server is not free. So, I decided to use MySQL instead. Hence, I need to find ways to configure Entity Framework on my project to work with MySQL.

The first tutorial that I started with is a detailed step-by-step guide on ASP .NET website regarding how to use use MySQL Storage with an Entity Framework MySQL Provider. It mainly involves steps on changing the web.config. Some important steps are listed below.

Change database connection string.

<add name="DefaultConnection" connectionString="Server=localhost;Uid=root;Pwd=password;Database=mediablog;" providerName="MySql.Data.MySqlClient" />

Configure Entity Framework to use MySQL.

<entityFramework codeConfigurationType="MySql.Data.Entity.MySqlEFConfiguration, MySql.Data.Entity.EF6">
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
        <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.9.5.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
    </providers>
</entityFramework>
<system.data>
    <DbProviderFactories>
        <add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.8.3.0" />
    </DbProviderFactories>
</system.data>

However, if I am not wrong, part of these can be done easily by just including the related MySQL nuget packages. I chose four of them to be installed in my project: MySQL.Data, MySQL.Data.Entity, MySQL,Data.Entities, and MySQL.Web.

Install related NuGet packages to make Entity Framework Code First works with MySQL.
Install related NuGet packages to make Entity Framework Code First works with MySQL.

After changing web.config, I followed the tutorial to introduce two new classes in the project. One is MySqlHistoryContext.cs which will sync the model changes with the database schema using MySQL standard and not MS SQL.

According to an online post, I added extra one line to the OnModelCreating method MySQLHistoryContext.cs. It’s to fix the exception of the famous Error 0040: The Type nvarchar(max) is not qualified with a namespace or alias. Only primitive types can be used without qualification.

modelBuilder.Properties<String>().Configure(c => c.HasColumnType("longtext"));

However, the Error 0040 didn’t disappear because of this line. I will share later the other steps I took to fix this problem.

The famous Error 0040 encountered when doing migrations for MySQL.
The famous Error 0040 encountered when doing migrations for MySQL.

Another new class is called MySqlConfiguration which is used to make sure the Entity Framework will use MySqlHistoryContext, instead of the default one.

Besides, I also made changes to Configuration.cs. Remember the Error 0040? A discussion thread on Github actually suggested to add the following line to fix it.

SetSqlGenerator("MySql.Data.MySqlClient", new MySql.Data.Entity.MySqlMigrationSqlGenerator());

This didn’t fix the Error 0040 on my project too.

In the end, I found a Chinese post which said the following.

此时只需要将Data层的Migrations的文件夹删掉即可。因为SqlServer做过一些迁移,有些数据类型与MySql不兼容。

The sentence basically says that due to the fact that the migration earlier done in SQL Server and thus some data types are not compatible with MySQL, we need to delete the Migrations folder. So, after I excluded the 201502231459263_InitialCreate.cs file (which was created when I am still using MS SQL for my project) in Migrations folder from the project, the Error 0040 was gone when I did Update-Database. Yay!

So yup, sometimes it’s very, very useful to know more than one language. And yup, I spent half of my holiday to figure out how to make Entity Framework to work with MySQL. =)

Oh well, half day gone just to make MySQL work in my little project.
Oh well, half day gone just to make MySQL work in my little project.

By the way, the Chinese web page mentioned above was already not available. What I shared with you is actually a link to its Google cached copy. I am not sure if the cache is still around when you visit it.

Self Learning ASP .NET MVC on MVA during Chinese New Year

The talks given during the community meetup are good. However, in order to learn more, I also need to get advice from my colleagues who have more experience with ASP .NET MVC.

In addition, during Chinese New Year period, instead of watching the new year shows, I stayed in front of my computer to complete the introductory series of ASP .NET MVC delivered by two Microsoft experts, Christopher Harrison and Jon Galloway. It’s definitely a good starting point for beginners. And yup, the two speakers are very good at explaining the key concepts and they also tell good jokes so you shouldn’t find the course to be boring. =P

Yup, people from Malaysia are watching the live too!
Yup, people from Malaysia are watching the live too!

The End of the Beginning

I am now still a beginner in ASP .NET MVC. I always find that there are many new things to learn in just web development. Actually, it’s very challenging. For example, to get Entity Framework Code First to work with MySQL already takes me half day to figure it out.

Anyway, this is just a post sharing how I get started on ASP .NET MVC. In the future, I will do my best to share with you all more about what I learn in this cool technology. =)

Dream – Build – Publish: My Experience in Microsoft Hackathon (2012 – 2014)

I already forgot how I got to know about Microsoft hackathon back in 2012, few months after I entered my first job.

Dream Build Launch, Wowzapp~

The first hackathon that I took part in is Dream Build Launch. I worked together with my C# guru, Desmond, to build our first Windows 8 app (which was called Metro App back then). We successfully published the app to Windows Store after two rounds of Microsoft Premier Field Engineer (PFE) consultation sessions. We named our first Windows 8 app “EsplanadeGo!”, which has 51 downloads today.

HTML5 for Metro Apps talk given by Alex Goh. Photo Credits: Spiffy
HTML5 for Metro Apps talk given by Alex Goh during Dream Build Launch event. Photo Credits: Spiffy

In December 2012, I participated in another Microsoft hackathon, Wowzapp. That was the first time I won the first prize in Microsoft competition after I graduated from university. The app that I built was called Entertainment Connect, also a Windows 8 app. User can use it to connect to his/her Dropbox account to retrieve media files and then play them in the app.

Near the end of the Wowzapp hackathon, one of the judges from Microsoft Singapore, Eugene, suggested me to build another app which connected to SkyDrive (which was later renamed to OneDrive) because he would love to use such an app and SkyDrive API was still quite new back then.

Because of Eugene’s idea of the app, I challenged myself again in the hackathon organized by Microsoft Singapore in 2014, //publish/. I decided to make Eugene’s dream come true.

//publish/

The special thing about //publish/ was that participants were allowed to bring their own existing Windows 8/8.1 projects. The focus of the event was more about publishing app to Windows Store. Hence, I took the opportunity to complete my second personal Windows 8 app, Entertainment Connect.

//publish/ hackathon was actually a 2D1N event happening worldwide. Personally, I thought the one in Singapore was the most special one because Inori Aizawa was invited as special guest to the event as well! Participants got the chance to take photo with her and won cute prizes. Also, we had the chance to try out Xbox One, the device that people were willing to queue up at Funan DigitaLife Mall for a few hours just to buy one.

Inori Aizawa and Xbox One! Photo Credits: Microsoft Singapore
Where else can you see Inori Aizawa playing Xbox One? Photo Credits: Microsoft Singapore
//publish/ organized by Microsoft in Singapore.
//publish/ organized by Microsoft in Singapore. Photo Credits: Microsoft Singapore

The event took place at The Co., a very comfortable place just next to my office. So, I got to bring laptop external keyboard and mouse, which helped to improve my coding speed.

There were tech talks given in the first morning. One of them was about Push Notification with Microsoft Azure. This talk in fact helped me a lot in my work when our company decided to do a push notification to Android and iOS phone.

Tech talk about Cortana delivered by Chun Siong.
Tech talk about Cortana delivered by Chun Siong. Photo Credits: Microsoft Singapore

Meet People

One of the great things that I love about Microsoft hackathon is that I always can meet imba people here. By just having a chat with them, I get to learn more technologies out there, such as Arduino, Azure Media Services, iOS development, and so on.

Because of this event, I also had the opportunities to make friend with Microsoft Singapore engineers who help me a lot in my work.

Entertainment Connect

Entertainment Connect is my submission for //publish/ in 2014.

Entertainment Connect
Entertainment Connect (Available now at Windows Store)

What’s so special about Entertainment Connect? Isn’t it just a media player that can play videos and songs? What else?

Firstly, yes, it is a media player. However, it is not a normal media player which can only play the local media files. It connects to your OneDrive account and retrieves available media files from there.

Secondly, I make it so that when you switch from one media file to another, the previous media file is paused and is hidden in the background. So, you can, let’s say, click on one video, play it halfway, then click on another song, then jump back to the same video again and continue from where you stop earlier. So this is actually similar to the “Parallel Video Downloading” feature that I introduced back then in YouTube Re-Player (Desktop) in 2009. The only difference is that now it does not limit the number of videos to be just 5.

Parallel Media Downloading from OneDrive to Entertainment Connect
Parallel Media Downloading from OneDrive to Entertainment Connect

Thirdly, it supports playing audio in the background. This means that even though the app is running in the background, users can still continue listening to the music and at the same time they can also control the media player.

SystemMediaTransportControls
SystemMediaTransportControls

Finally, it can loop songs and videos. Yup, re-playing is always the must-have feature in the media player programs that I build. =)

Wait, It Was 6 Months Ago!

Some of the readers by now should have realized that //publish/ actually happened 6 months ago. Why do I only blog about it now? Well, the answer is that I choose to blog about it after I successfully publish Entertainment Connect to Windows Store. So, why does it take so long for me to publish an app? This is because I have little time to work on it after the event.

Simple to-do list kept in OneNote
Simple to-do list kept in OneNote

I have learnt the key to finishing a personal project is to work on the project every day. However, I have a full-time work which requires me to OT always. Sleeping has thus become my top priority after work. However, I still try to at least work on the project by writing a few lines of code or just staring at Visual Studio for a few minutes. So, after 6 months of doing so, I am finally able to publish Entertainment Connect.

There is a saying, “Only do side projects you are absolutely crazy about.” Hence, I also installed Entertainment Connect on my laptop so I got to use it daily. The reason of doing so is to force me to remember about the project and to easily find out bugs in the app.

Today, I am happy that I successfully realize the dream of Eugene about a Windows 8 app that he can use to connect to play the media files stored in his OneDrive. In fact, I am very happy to have taken up this challenge and complete the app by myself even though the entire process is tiring.

Prize

Prize is Nokia Lumia 1520!
Prize is Nokia Lumia 1520!

I’d also like to take this chance to thank Microsoft Singapore team for giving me a special prize for Entertainment Connect during //publish/. It was a brand new Nokia Lumia 1520. Coincidentally, my Android phone stopped functioning few days before the event. So, I managed to get a new modern smart phone for free.

I should blog about the phone next time to show how good/bad Nokia Lumia 1520 is. =P

Downloads

Entertainment Connect is now available at Windows Store. You can visit the page http://apps.microsoft.com/windows/en-us/app/entertainment-connect/41d91a6b-6b56-4ae8-94b9-9b5f1053ca92 to download it now. It is free. =)

For developers who are interested to read the codes of app written in WinJS, please checkout the source code of Entertainment Connect on GitHub: https://github.com/goh-chunlin/EntertainmentConnect.

Entertainment Connect is now on GitHub!
Entertainment Connect is now on GitHub: https://github.com/goh-chunlin/EntertainmentConnect!

February Self-Learning: Let’s Take a Tour to Malaysia with HTML5

February is a short month so I have to plan my self-learning accordingly so that I can get myself more focused. Due to the fact that I can only spend on average one hour per day to work on my personal project and self-learning, I choose to learn not only something which is easier, faster to learn, but also a technology that is more interesting. So, the topic of February self-learning is HTML5! (Notice/Joke: ! is exclamation mark here. It doesn’t mean 5! which equals to 120).

Canvas

Canvas element is indeed an exciting addition to HTML5. Thanks to <canvas>, we can now draw graphics on the web page easily via, for example, JavaScript. I have seen many people trying to use CSS to do drawing. There are even people successfully using CSS to render Homer Simpson. Oh my tian. It’s a fun thing to draw stuff in CSS but it’s just a hack after all.

Draw in CSS? Come, I clap for you.
Draw in CSS? Come, I clap for you.

I do a firefly animation by using this new <canvas> element in a simple way. Firstly, I draw some fireflies on the canvas.

cxt.globalAlpha = 0.4;
cxt.beginPath();
cxt.arc(x, y, ((fireflyLightMaxDiameter - fireflyDiameter) * brightnessRatio) + fireflyDiameter, 0, Math.PI * 2, true);
cxt.closePath();
var grd = cxt.createRadialGradient(x, y, 1, x, y, 4);
grd.addColorStop(0, "#FFFFFF"); // white
grd.addColorStop(1, "#FFFF00"); // yellow
cxt.fillStyle = grd;
cxt.fill();
cxt.globalAlpha = brightnessRatio;
cxt.fillStyle = "#99FF00";
cxt.beginPath();
cxt.arc(x, y, fireflyDiameter, 0, Math.PI * 2, true);
cxt.closePath();
cxt.fill();

Secondly, I will redraw the whole canvas for every 60 milliseconds. Then in each redraw function, I randomly assign flying speed and direction to every single firefly. Also, there is a counter set so that the firefly won’t change its direction too often.

dx = Math.floor(Math.random() * fireflyMaxSpeed);
dy = Math.floor(Math.random() * fireflyMaxSpeed);
firefliesDx[i] = dx;
firefliesDy[i] = dy;
x += dx * directionX[i];
y += dy * directionY[i];
if (callCounter % 40 == 0) { // Don't change the flying direction too often
    directionX[i] = ((Math.floor(Math.random() * 10) < 5) ? 1 : -1);
    directionY[i] = ((Math.floor(Math.random() * 10) < 5) ? 1 : -1);
}

Thirdly, I set a counter to do the brightness changing of each firefly.

brightness[i] += fireflyBrightnessSpeed * brightnessDirection[i];
if (brightness[i] > fireflyMaxBrightness) {
    brightnessDirection[i] = -1;
} else if (brightness[i] < 0) {
    brightnessDirection[i] = 1;
}

So, yup, that’s the basic idea on how I  do firefly animation in <canvas>. Since this year is the tourism year in my country, I apply the firefly animation in a page about watching fireflies in Kuala Selangor, Malaysia. To get the source code, you can visit my page of this animation in the Mozilla Demo Studio. Don’t forget to click “Like It” button if you really like it. =P

Firefly HTML5 Animation
Firefly HTML5 Animation: The page is to promote Kuala Selangor, the world’s biggest firefly colony

Popcorn.js: Integrating Video and the Web Content

However, promoting just one attraction in my country is not enough. So, I am thinking of building a page which will guide the viewer through different places in Malaysia.

I get a promotional video about Malaysia tourism from YouTube. In the video, it shows several famous tourist attractions in Malaysia. I want to build a web page showing a short introduction as well as a map (or even street view) about those places. I thus chose Popcorn.js.

Popcorn.js is an open-source HTML5 video framework which allows us to create time-based interactive media on the web. So, we can now bring content in a web page into a video easily. People watching a video on the website now can also read a web page content which is relevant to the video content. So, this JavaScript library basically allows to add value to a video.

The following screenshot shows how the page looks when the video is displaying a picture of Pulau Tenggol.

Popcorn.js in action.
Popcorn.js in action.

YouTube Plug-in Issue in Popcorn.js

There is a problem if we are using the YouTube plug-in offered in the Popcorn.js. After the video ends, the YouTube player will show a group of relevant videos. So it basically allows the viewer to change the content of the video player. Hence, to solve this problem, I added one value to the playerVars in popcorn.js.

playerVars = { wmode: "transparent", rel: 0 };

By default, rel is 1. The rel parameter in YouTube Player API indicated whether related videos should be shown in the player after the video finishes. So setting it to 0 fixes the problem.

CSS Animation

Although it’s not encouraged to use CSS to do complicated drawing on the web pages, thanks to the CSS3, we can now create animations with CSS by using @keyframes. For example, the following is part of my CSS which does the animation of the name of each attraction in the web page.

#footNote h1 {
    -webkit-animation:blurFadeIn 5s; 
    animation:blurFadeIn 5s; 
    font-family:KaiTi 隶书 Arial;
}
@-webkit-keyframes blurFadeIn{
    0%{
        opacity:0;
        text-shadow:0px 0px 40px #fff;
        -webkit-transform:scale(1.5);
    }
    100%{
        opacity:1;
        text-shadow:0px 0px 1px #fff;
        -webkit-transform:scale(1);
    }
}
@keyframes blurFadeIn{
    0%{
       opacity:0;
       text-shadow:0px 0px 40px #fff;
       transform:scale(1.5);
    }
    100%{
       opacity:1;
       text-shadow:0px 0px 1px #fff;
       transform:scale(1);
    }
}

What it does is basically just a simple fade-in animation of the text.

To view the finalized version of the web page, please visit to my page on Mozilla Demo Studio.

Visit Malaysia 2014

Both of the web pages mentioned above are all about Malaysia tourism. Why? This is because this year, Malaysians are having the nation’s largest tourism celebration. We had one back in 2007 when we were celebrating the 50th years anniversary of independent in Malaysia. Then Prime Minister, Abdullah Ahmad Badawi, even showed up in the Visit Malaysia 2007 promotional video.

So, if you haven’t visited Malaysia before, please bring your family and friends to this lovely country and join us in this grand tourism celebration. However, before that, kindly vote for my following two demos by clicking the “Like It” button. Thanks. =D

Enjoy the HTML5 firefly animation here.
Enjoy the HTML5 firefly animation here.
Take a tour to Malaysia with HTML5 here.
Take a tour to Malaysia with HTML5 here.