React & ASP.NET Core

React is getting very popular for building rich web interface, and is one of the supported project template in ASP.NET Core. In .NET Core, you can quickly create a new React project by running the command (or using the new project dialog):

The template immediately gives you a working project with both React and ASP.NET Core. However, I don’t feel very happy with the latest template in .NET Core 2.2 and 3.0, so I created a new one based on the template from older version of .NET Core for my own projects.

Read More

What I’ve learned moving from Azure WebJobs to Azure Function Apps

Updated: some previous of the content in this post is no longer applicable when you upgrade Microsoft.NET.Sdk.Functions to version 1.0.26, so I have added some notes and sections on that.

If you have been using Azure for some times, you might know about Azure WebJob, a great way to run your code in background on triggers and integrate with other services via bindings. Recently, Azure introduced a similar offering: Azure Function App. Function App is based on a very similar idea, where you can run your code in any supporting languages on certain triggers such as a Queue message or a HTTP request or a timer.

We have been using Azure WebJob for a couple of years to process our email/push notifications and to clean up of our database. WebJob served that purpose perfectly until our app growth reveals a big limitation: WebJob consumes all the resource of the web app itself. In theory, WebJob should be a separate background process and should not interfere with the web app. However, since it is inside the App Service, it utilizes the same CPU/Memory consumption constraint of the App Service Plan. We started getting downtime alert from our APIs because the WebJob is running too heavily, defeating the purpose of splitting up some processing to a separate process in the first place.

We look around for solutions. First of all, we tried scaling out the app service plan based on CPU and memory consumption. However, it was hard to set a proper rule to scale up and down, and the cost multiplied quite quickly. We started looking at moving to Azure Function App with consumption plan. On paper it looks great because we can completely separate our background processing and our API. We also does not have to waste computing resources for the WebJob dashboard as telemetry is now sent to Application Insights instead of Azure Storage (I heard the WebJob dashboard consumed App Service Plan’s CPU to perform certain indexing).

Unfortunately, the migration was not as smooth as we thought. We soon met many problems with our C# implementation:

  • If you are using Timer trigger in Function with consumption plan, remember that you have to use the CRON schedule format (0 0 */8 * * *), not the Timer format (08:00:00).
  • (This is no longer applied for Microsoft.NET.Sdk.Functions 1.0.26) Using QueueTrigger, you’ll get an amazingly cryptic error message on Azure Dashboard: The binding type(s) ‘queueTrigger’ are not registered. Please ensure the type is correct and the binding extension is installed. Visual Studio generated a functions.json with binding queueTrigger and can be seen on the Azure portal. We also added queues section to host.json file. We have also installed Microsoft.Azure.WebJobs.Extensions.Storage to enable QueueTrigger in code. So what did we miss here? Turn out you have to add
    Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator nuget package as well, so that Visual Studio will generate extensions.json.
    This is not mentioned anywhere in the docs but only a small page on GitHub, which is very irritating.
  • If you are using Microsoft.NET.Sdk.Functions 1.0.26 and are using the above workaround, extensions.json might not be generated in the correct place, and you would suddenly get the same issue with unregistered binding types again when testing locally. You can try to remove Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator and let the SDK handle the json generation.
  • ILogger is supported by the new WebJob SDK since the migration to .NET Core and also by Function SDK v2, which is great since our Functions can finally share code with ASP.NET Core. Unfortunately, you might get error “Cannot bind parameter ‘log’ to type ILogger. Make sure the parameter Type is supported by the binding.” Turn out you need to use the exact version of ILogger in the SDK (e.g. SDK 1.0.19 uses 2.1.0) (stackoverflow), which would be a big problem if one of the dependencies updates to higher versions.

There are also several limitations that is probably due to Function App being a quite young platform in Azure:

  • It seems that Function is actually based on WebJob behind the scene, so the features set of Function SDK in C# is only a subset of that of WebJob:
    • (This is no longer applied for Microsoft.NET.Sdk.Functions 1.0.26) WebJob recently moved to .NET Standard and get the extremely convenient dependency injection. Meanwhile, there is no DI story in Function. This might be ok with small function, but ours get a lot of logic and we would like to have DI to get proper tests.
    • If you are using Microsoft.NET.Sdk.Functions 1.0.26, you can check out this blog post on the new DI support https://platform.deloitte.com.au/articles/performing-constructor-injections-on-azure-functions-v2.
    • A small extra note: if previously you have been using SetBasePath(context.FunctionAppDirectory) to read configuration in local.settings.json. You can now use SetBasePath(Directory.GetCurrentDirectory()) in your startup class.
  • The current dashboard experience in Azure portal lacks the ability to replay the execution. This is not really critical for applications that have already been in production for a while as you should already have some retry mechanisms. However, it is quite convenient for development and small testing. Hopefully this will come soon in the future.

If you have any better solutions for those problems, please feel free to let me know in the comments.

The curious case of missing Authorization header

I have been wasting time on a small issue adding Authorization header into HttpClient.

The code was plain and simple:

Specifically, I was writing a .NET Core console app, following this wiki page https://github.com/projectkudu/kudu/wiki/Accessing-the-kudu-service and trying to access http://mysite.scm.azurewebsites.net/basicauth. However, I kept getting 401 Unauthorize response and response.RequestMessage.Headers was completely empty.

After having spent some time searching for solution on the Internet but to no avail, I opened Fiddler to see the actual HTTP requests. Turns out, this was what happened behind the scene:

There were actually 2 requests. The first one has the Authorization header and returns a 302 Found. Automatic redirection of HttpClient triggers the second request, and this one didn’t have any Authorization header.

Normally I can just stop there, accept that how things work in .NET and find a workaround. But since .NET Core is open source on GitHub, I decided to dig a bit deeper to understand the reason of this implementation. A quick search about redirection on the corefx repo in GitHub gave me the exact commit that I need: https://github.com/dotnet/corefx/commit/e8a17715fba4ba6cfce4043a2cd117474dfcee05. And voila, I could see the line in RedirectHandler.cs that causing the issue:

and I could also see the reason in SocketsHttpHandler.cs:

 

I finally solved my curious case, and I hope this post is useful to you. Feel free to leave me a comment and let me know if you have any suggestion on securely implement the redirection with Authorization header.

 

How to integrate Teamcity and GitLab CI

I note down the step I did to integrate TeamCity build server and GitLab CI pipeline. I am using TeamCity 2017.1.15 and GitLab 10.0.3.

What you will get with this integration:

  • Small green tick for each commit showing that a build has run successfully on the commit
  • Bigger tick for each merge request (MR) showing that a build has run successfully on the head of the merge request
  • Ability to enforce a successful build before any MR can be merged

How to set up the integration

Tldr, you need to go through 3 main steps:

  1. Enable TeamCity integration in your GitLab project settings
  2. Enable TeamCity build configuration to monitor and trigger build for all (CI) branches
  3. Enable “Commit status publisher” build feature

Read More

Building a small running bot with Windows 10 on a Raspberry Pi 2

I won a Raspberry Pi B+ from a Microsoft event, so I took some time to learn about the Pi to understand more about all the fuzz around IoT. The experience I had is very fun and excited. I study and work mainly on software engineering, so hacking the virtual world is much more familiar to me that hacking those hardware and devices in the real world. However, Raspberry Pi turned out to be the perfect device for me to learn more about this IoT area by providing a bridge between high level programming language (such as Python) and all the “complicated” GPIO and I2C stuffs. In other words, you can write Python instead of C++ or Assembly to communicate with so many electrical boards and devices. There are many interesting and easy to follow tutorials on Adafruit that I strongly recommend you to take a look and give it a try.

With the introduction of Windows 10 on Raspberry Pi 2, the small computing box becomes even more interesting to me. The Pi can now run Universal Windows apps and communicate with devices such as Xbox controller. Therefore, I have decided to buy a new Pi 2 and give Windows 10 IoT a try with a new project: a running robot that is remotely controlled with a Xbox Controller.
Read More