Tuesday Reading List

Inventory Dashboards Using the Power of Azure Resource Graph

Ever wonder what are all the resources in your Azure environment? You can now use power of Azure Resource Graph to query all the resources (or filter based on certain criteria).


Capture Web Application Logs with App Service Diagnostics Logging

Ever confused what logs are available in Azure? Well, I’m too. Specfically for Azure App Service however, the learning module helps you understand what’s your options.


Improve the developer experience of an API with Swagger documentation

Use Swagger in your next API project and you won’t have to hand-written those documentations. Heck, even use it in your existing API projects! This learning module will teach you how to implement Swagger in your ASP.NET Core API


10 GREAT .NET CORE 3.0 ARTICLES YOU MUST HAVE A LOOK

Never get enough of .NET Core 3.0? Well, these 10 articles should give you enough read for the week. From performance, migration to configuration, it covers lots of stuff you want to know about .NET Core 3.0.


The ultimate (free) CI/CD for your open-source projects

You probably already know, but maintaining open source project is difficult and take a lot of your time. So, if you could automate your CI/CD and it’s free? Sure, why not.


WebApi .Net – Add DelegatingHandler to Get Request Body

Out of the box, WebApi pipeline bind request body to parameter, therefore WebApi Controller (which inherit from ApiController) `Request.Content` object is empty.

For example, passing this json in the request body:

[
    {
        "Name": "Test",
        "Status": "C",
    }
]

Will bind it to WebApi Controller’s parameter, however, `Request.Content` object is empty.

screenshot message handler

Overcome this issue by creating `DelegatingHandler` to add request body back.

RequestHandler.cs

using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace QC
{
    public class RequestHandler : DelegatingHandler
    {
        protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            // Request body stream is emptied when WebApi bind request body to parameter, here we add original request body back so we can access it
            if (request.Content != null)
            {
                string body = await request.Content.ReadAsStringAsync();
                request.Properties["body"] = body;
            }

            return await base.SendAsync(request, cancellationToken);
        }
    }
}

Register in WebApiConfig.

WebApiConfig.cs

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MessageHandlers.Add(new RequestHandler());
    }
}

Viola! `Request.Content` contains request body.

screenshot message handler2

Code is from here.

Web API .Net with Basic Authentication

Github project.

Notes:
1. This work on .Net framework 4.6.1.
2. Authorization part is not covered.

The core authentication code is in `Security/BasicAuthAttribute.cs`. This class inherit from following:

ActionFilterAttribute
So we can use it as attribute to decorate controllers or actions.

IAuthenticationFilter
To invoke WebApi’s authentication pipeline. Some developer like to use `IActionFilter` for authentication, while it may work, it is not a best practice as `IActionFilter` execute later in the WebApi stack.

IAuthenticationFilter implement 2 methods:
1. `AuthenticateAsync`. Run first. This is code to authentication user. Caller pass in credential in request header. First we begin by parsing the header and user name/password credential caller passed in. Then authenticate user, in Github project, I add user to generic principal but in production app, you should validate credential against security provider (ie: ADFS, Auth0), etc.
2. `ChallengeAsync`. Run after `AuthenticateAsync`. This is where authentication failed and we can challenge caller to prove them selves, which is done by passing `Authorization Basic` in response header.

Usage
There are 3 ways to use this attribute in WebApi.
1. Globally. Every actions will require authentication.

WebApiConfig.cs

public static void Register(HttpConfiguration config)
{
    // Add global authentication
    config.Filters.Add(new BasicAuthAttribute());

    // Web API routes
    config.MapHttpAttributeRoutes();

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}

2. In entire controller. Every actions under that controller will require authentication. Notice the `[BasicAuth]` decoration.

ValuesController.cs

[BasicAuth]
public class ValuesController : ApiController
{
    public IEnumerable Get()
    {
        return new string[] { "value1", "value2" };
    }
            
    public string Get(int id)
    {
        return "value";
    }
}

3. In specific action. Notice the `[BasicAuth]` decoration.

ValuesController.cs

public class ValuesController : ApiController
{
    public IEnumerable Get()
    {
        return new string[] { "value1", "value2" };
    }

    [BasicAuth]
    public string Get(int id)
    {
        return "value";
    }
}

How to Implement IExceptionLogger and IExceptionHandler in Web Api .Net

This works on Web Api 2+ and MVC 5+.

1. Create implementation of ExceptionHandler class. Note this class inherit from concrete class of ExceptionHandler, not the interface. Inherit from concrete class decrease effort to implement other methods.

using System.Threading;
using System.Threading.Tasks;
using System.Web.Http.ExceptionHandling;

namespace BlahBlahBlah.ExceptionHandler
{
    public class GlobalExceptionHandler : System.Web.Http.ExceptionHandling.ExceptionHandler
    {
        public override Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
        {
            // Code to handle exception...

            return base.HandleAsync(context, cancellationToken);
        }
    }
}

2. Create implementation of ExceptionLogger class. Note this class inherit from concrete class of ExceptionLogger, not the interface. Inherit from concrete class decrease effort to implement other methods.

using System.Threading;
using System.Threading.Tasks;

namespace BlahBlahBlah.ExceptionHandler
{
    public class GlobalExceptionLogger : System.Web.Http.ExceptionHandling.ExceptionLogger
    {
        public override Task LogAsync(System.Web.Http.ExceptionHandling.ExceptionLoggerContext context, CancellationToken cancellationToken)
        {
            // Code to log exception...

            return base.LogAsync(context, cancellationToken);
        }
    }
}

3. Replace default Logger and Handler.

using System.Web.Http;
using System.Web.Http.ExceptionHandling;
using BlahBlahBlah.ExceptionHandler;

namespace BlahBlahBlah
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {            
            // Replace default exception handler and logger
            config.Services.Replace(typeof(IExceptionLogger), new GlobalExceptionLogger());
            config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler());

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

If you wonder difference between IExceptionLogger and IExceptionHandler, this is from Microsoft docs:

We provide two new user-replaceable services, IExceptionLogger and IExceptionHandler, to log and handle unhandled exceptions. The services are very similar, with two main differences:

1. We support registering multiple exception loggers but only a single exception handler.
2. Exception loggers always get called, even if we’re about to abort the connection. Exception handlers only get called when we’re still able to choose which response message to send.

Both services provide access to an exception context containing relevant information from the point where the exception was detected, particularly the HttpRequestMessage, the HttpRequestContext, the thrown exception and the exception source (details below).

Application Insights Intrumentation Key in Web.config

When using Azure Application Insights in ASP.Net application, by default, Visual Studio insert IntrumentationKey in ApplicationInsights.config.

To allow multiple environments tracking, move IntrumentationKey to Web.config by following this steps:

  1. Remove IntrumentationKey from ApplicationInsights.config. If you have MVC application, don’t forget to modify ApplicationInsights’ script (usually in View\Shared\_Layout.cshtml), replace:

    {instrumentationKey:"your instrumentation key"}
    

    with:

    {instrumentationKey:"@Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.Active.InstrumentationKey"}
    
  2. Add new app settings for IntrumentationKey in Web.config under <appSettings>

    <add key="InstrumentationKey" value="your instrumentation key" />
    
  3. In Global.asax.cs, Application_Start() method, add:

    Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.Active.InstrumentationKey = System.Web.Configuration.WebConfigurationManager.AppSettings["InstrumentationKey"];
    

That’s it for the configuration changes. Everything else is the same including tracking custom event or page view.
With this configuration, you will be able to define InstrumentationKey in Release management for each environments.

ASP.Net Web API Pipeline

Similar to ASP.Net MVC but not exactly the same. Pedro Felix has this self-explanatory graph depicting ASP.Net Web API

asp-net-web-api-pipeline

Head over to the full article, ASP.Net Web API Processing Architecture 

Claims-Based Authorization in ASP.Net MVC and Web Api

Normally, I would re-write a blog post in hope to provide better explanation and concise the article, but since this is from Dominick Baier, I think he does it the best.

So, here’s it, how to apply claims based authorization in ASP.Net MVC and Web Api:

http://leastprivilege.com/2012/10/26/using-claims-based-authorization-in-mvc-and-web-api/

Dependency Injection in Web API With Unity IoC

WebApiConfig.cs

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var container = new UnityContainer();
        container.RegisterType<IProductRepository, ProductRepository>();
        config.DependencyResolver = new UnityResolver(container);

        // Other Web API configuration not shown.
    }
}

Global.asax.cs

protected void Application_Start()
{
    // Some code here...

    WebApiConfig.Register(GlobalConfiguration.Configuration);

    // Some code here...
}

Version attow: Unity 3, Web API 2

Learning Paths

With so many tutorials, articles and resources available out there on the Internet, learning new programming language, framework and library become much more easier. However, as much as its advantage, readily available resources have also become its own problem: where should I start?

With so many options available, it can be confusing to even start learning. I present you my learning paths to solve this problem. Learning paths will guide you through learning programs for each subject of your interests. Think of this as a curriculum to the degree you want to get.

Most of the courses are from Pluralsight.com, but this learning paths are not limited to just Pluralsight.com. I also include some free courses from other sources. While I understand that you may have to pay for some of these courses, I can assure you that paying the subscription is worth it (especially Pluralsight!).

I will update this learning paths to include more subjects and courses in the future. Stay tuned!

Android

Level Course
0100 Get the Android SDK (http://developer.android.com/sdk/index.html)
0101 Prerequisite: 0100
Getting Started (http://developer.android.com/training/index.html)
0102 Introduction to Android Development (http://pluralsight.com/training/Courses/TableOfContents/android-intro)
0200 Prerequisite: 0101 or 0102
Android Async Programming and Services (http://pluralsight.com/training/Courses/TableOfContents/android-services)

AngularJS

Level Course
0100 AngularJS Fundamentals (http://pluralsight.com/training/Courses/TableOfContents/angularjs-fundamentals)
0200 Prerequisite: 0100
AngularJS In-Depth (http://pluralsight.com/training/Courses/TableOfContents/angularjs-in-depth)
0201 Prerequisite: 0100
Testing AngularJS From Scratch (http://pluralsight.com/training/Courses/TableOfContents/testing-angularjs-from-scratch)

ASP.NET MVC

Level Course
0100 ASP.NET MVC Fundamentals (http://pluralsight.com/training/Courses/TableOfContents/aspdotnet-mvc)
0200 Prerequisite: 0100
ASP.NET MVC 5 Fundamentals (http://pluralsight.com/training/Courses/TableOfContents/aspdotnet-mvc5-fundamentals)

ASP.NET Web API

Level Course
0100 Introduction to the ASP.NET Web API (http://pluralsight.com/training/Courses/TableOfContents/aspnetwebapi)
0200 Prerequisite: 0100
Web API v2 Security (http://pluralsight.com/training/Courses/TableOfContents/webapi-v2-security)
0201 Prerequisite: 0100
Web API Design (http://pluralsight.com/training/Courses/TableOfContents/web-api-design)

C#

Level Course
0100 C# Basic (http://csharp-station.com/Tutorial/CSharp)
0101 C# From Scratch (http://pluralsight.com/training/Courses/TableOfContents/csharp-from-scratch)
0102 Prerequisite: 0101
C# From Scratch – Part 2 (http://pluralsight.com/training/Courses/TableOfContents/csharp-from-scratch-part2)
0200 Prerequisite: 0100 or 0102
Object-Oriented Programming Fundamentals in C# (http://pluralsight.com/training/Courses/TableOfContents/object-oriented-programming-fundamentals-csharp)

Entity Framework

Level Course
0100 Getting Started with Entity Framework 5 (http://pluralsight.com/training/Courses/TableOfContents/entity-framework5-getting-started)
0200 Prerequisite: 0100
Entity Framework Code First Migrations (http://pluralsight.com/training/Courses/TableOfContents/efmigrations)

JavaScript & jQuery

Level Course
0100 W3Schools’s JavaScript Tutorial (http://www.w3schools.com/js/default.asp)
0101 JavaScript Fundamentals (http://pluralsight.com/training/Courses/TableOfContents/jscript-fundamentals)
0120 Prerequisite: 0100 or 0101
DO Factory’s JavaScript + jQuery Design Pattern Framework – JavaScript & Pattern Essentials (http://www.dofactory.com/products/javascript-jquery-design-pattern-framework)
0200 Prerequisite: 0100 or 0101
JavaScript Design Patterns (http://pluralsight.com/training/Courses/TableOfContents/javascript-design-patterns)
0300 Prerequisite: 0200
jQuery Fundamentals (http://pluralsight.com/training/Courses/TableOfContents/jquery-fundamentals)

WIF, Claims-based Identity, OAuth2

Level Course
0100 Introduction to Identity and Access Control in .NET 4.5 (http://pluralsight.com/training/Courses/TableOfContents/iac-intro)
0200 Prerequisite: 0100
Identity and Access Control in ASP.NET 4.5 (http://pluralsight.com/training/Courses/TableOfContents/iac-aspnet)
0201 Prerequisite: 0100
Identity and Access Control in WCF 4.5 (http://pluralsight.com/training/Courses/TableOfContents/iac-wcf)
0202 Prerequisite: 0100
Web API v2 Security (http://pluralsight.com/training/Courses/TableOfContents/webapi-v2-security)
0300 Prerequisite: 0200 or 0201 or 0202
Introduction to OAuth2, OpenID Connect and JSON Web Tokens (JWT) (http://pluralsight.com/training/Courses/TableOfContents/oauth2-json-web-tokens-openid-connect-introduction)

ASP.NET Web API and OData’s Verbose JSON

OData v3 and Verbose JSON

Whenever you work with OData in ASP.NET Web API, the return result will be JSON format. It’s noteworthy to know that by default Web API will return new OData JSON format specified in OData version 3. For older OData, the JSON format is different. It has more ‘unnecessary’ placeholders. This old OData JSON is also referred as ‘Verbose JSON’. In short, there are two types of OData JSON:

  • OData v3 has new JSON format
  • Verbose JSON is used in older OData versions.

ASP.NET Web API (.Net 4.5) and Verbose JSON

As mentioned before, by default Web API will return new OData JSON.

To change this behavior, you can request Web API to return old OData JSON format by specifying ‘odata=verbose’ in Accept header. Below is the sample of jQuery Ajax call specifying verbose JSON:

$.ajax({
    url: "/api/Products",
    dataType: "json",
    accepts: { json: "application/json;odata=verbose" }
}).done(function() {
    // do work ...
});

How it Looks Like?

For the curious:

Verbose JSON

{
    "d" : {
        "results": [
            {
                "__metadata": {
                    "uri": "http://demos/Orders(10248)",
                    "type": "SampleModel.Order"
                },
                "ProductId": 10248,
                "Name": "Vgnon"
            }
        ],
        "__count": "1"
    }
}

OData v3 (and above) JSON

{
    "odata.metadata":"http://localhost:43111/api/$metadata#Products",
    "odata.count":"1",
    "value":
    [
        {
            "ProductId":2,
            "CreatedDate":"2013-06-10T23:53:26",
            "CreatedBy":0,"Name":"Camera"
        }
    ]
}