Read Request Content in Web API

In some scenarios, we must read the http request content as string, and parse the string ourselves.

public IHttpActionResult POST() 
     string requestContent = ReadRequestContent(Request).Result;        
     return OK(requestContent);
private async Task<string> ReadRequestContentAsync(
                               HttpRequestMessage Request)
     string result = await Request.Content.ReadAsStringAsync();        
     return result; 




Customize IHttpActionResult in WEP API 2

According to [1], some advantages of using the IHttpActionResult interface are:

  1. Simplifies unit testing your controllers.
  2. Moves common logic for creating HTTP responses into separate classes.
  3. Makes the intent of the controller action clearer, by hiding the low-level details of constructing the response.

Today, we are going to customize IHttpActionResult to create a class VersionedTextResult to support API versioning based on TextResult in [1].

public class VersionedTextResult : IHttpActionResult
    string _value;
    string _version;
    HttpRequestMessage _request;

    public TextResult(string value, string version, 
			HttpRequestMessage request)
        _value = value;
        _version = version;
        _request = request;

    public Task<HttpResponseMessage> ExecuteAsync(
        CancellationToken cancellationToken)
        var response = new HttpResponseMessage()
            Content = new StringContent(_value),
            RequestMessage = _request
        var responseHeadersContentType = 
        NameValueHeaderValue versionParamter = 
            new NameValueHeaderValue("version", Version);
        return Task.FromResult(response);




C# Async and Await Revisit

In my last post about async and Await, I forgot to mention to use Task<TResult>.Result to pause the control flow and get the results immediately. In these code blocks, I showed two locations to use Task<TResult>.Result, and location 2 is the preferred location since we are taking advantage of async programming.


static void Main(string[] args)
  Console.WriteLine("Main ThreadId: "
    + Thread.CurrentThread.ManagedThreadId + ", start" + "\r\n");

  AsyncAwaitTest aa = new AsyncAwaitTest();
  Task<int>[] tasks = new Task<int>[5];
  for (int i = 1; i <=5; i++)
    tasks[i-1] = aa.GetStringAsync(i);
    // Location 1
    // If we uncomment the following line, it will force the program 
    // to sync mode and get the result immediately 
    // Console.WriteLine("Task : " + i + ": " + tasks[i - 1].Result);

  Console.WriteLine("Main ThreadId: " 
    + Thread.CurrentThread.ManagedThreadId 
    + ", control back (UI responsive)." + "\r\n");

    for (int i = 1; i <=5; i++) 
        // Location 2
        // The preferred location 
        // since we are taking advantage of async programmin
        Console.WriteLine("Task : " + i + ": " + tasks[i - 1].Result); 

public class AsyncAwaitTest
  public async Task GetStringAsync(int workerNumber)
    Console.WriteLine("Worker #" + workerNumber + ", ThreadId: "
      + Thread.CurrentThread.ManagedThreadId
      + ", begin to process tons of data here ... ");
    var httpClient = new HttpClient();
    Task getStringAsync = 
    string content = await getStringAsync;
    int length = content.Length;
    Console.WriteLine("Worker #" + workerNumber + ", ThreadId: "
      + Thread.CurrentThread.ManagedThreadId + ", finished");
    return length;

Dependency Injection Tip: Swap Runtime Environments

We design our apps with design principles and best practices. The resulting apps usually have dependency injection in place already. We then can use Ninject as the dependency injection tool, and set up in-memory test objects along with our production codes.

The question is that how can we click a button to swap the in-memory test environment and debug/release environment easily?

Luckily, there are  two features in Visual Studio, build configuration and conditional compilation, which can solve our problem easily.

  1. In VS solution, create a new build configuration, InMemory, and choose to inherit the setting from Debug.
  2. Add a constant ‘INMEMORY’ to the ‘Conditional compilation symbols’ in the ‘Build’ tab of project property.
  3. Add conditional compilation in Ninject’s Register Services code block


/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name=”kernel”>The kernel.</param>
private static void RegisterServices(IKernel kernel)


Git: What it is in 5 minutes


Git is a light-weight distribution version control system.

Git is built on 4 layers of abstractions like an onion, and each layer is based on another.

  1. Persistent map. The technical cornerstone is SHA1, a hashing algorithm.
  2. Content tracker
  3. Version control
  4. Distribute version control

A few things worth noting technically.

  1. Git is path independent because it is based on persistent maps.
  2. It is inherently easy to understand. It only has four types of objects, blob, tree, comment, tag.
  3. A branch is just a commit. This idea really blew me away because I never think from this perspective. Branching is super easy to understand.
  4. A commit is a snapshot of the persistent map.
  5. Rebase. Nice concept if used correctly
  6. Good fit for distributed peers like open source projects



  1. Paolo Perrotta, How Git Works, Pluralsight

Microsoft Azure: Stack, Private, Public, Hybrid

There are Azure Stack, Private/Public/Hybrid Cloud in In Microsoft Azure.

Private Cloud: Azure on premise. An enterprise has to keep some apps and data on premise by regulations.

Public Cloud: Cloud hosted by Microsoft.

Hybrid Cloud: An enterprise uses both private and public cloud.

Azure Stack: in fact, it’s a private cloud. All the VMs, containers, app services, etc., are compatible and transferable seamlessly to public cloud if needed.



Cloud: IaaS vs PaaS vs SaaS

Cloud can be simplified as the combination of IaaS, PaaS, and SaaS.

IaaS: Infrastructure as a Service. Tenants maintain apps and VMs, and vendors maintain the hardware. Example: Amazon’s EC2, Microsoft’s Azure VMs, etc.

PaaS: Platform as a Service. Tenants focus on core business and maintain relevant core business apps only, and delegate the responsibilities of VMs and hardware to vendors. Tenants deploy apps and codes to a platform vendors provide. Example: Azure’s app service, Amazon’s Elastic Beanstalk

SaaS: Software as a Service. Tenants focus on core business and choose relevant vendors’ software offerings, and delegate the responsibilities of software, VMs, and hardware to vendors. Examples: Gmail, Sky Drive, Dropbox, SharePoint online, Office online, Salesforce, etc.

Table 1. Responsibilities of Tenants and Vendors

  IaaS PaaS SaaS
Apps  Tenants  Tenants  Vendors
VMs  Tenants  Vendors  Vendors
Hardware  Vendors  Vendors  Vendors



A Black Screen for Azure VM after a Successful RDP login?

I got another black screen issue. However, it was different this time because the black screen was a Azure VM.

Tried my favorite command, CTRL+ALT+END. It failed. Googled and tried different approaches. Some approaches just were too complicated so I gave up those.

Finally, came across the SO thread [1], and it was the second answer to download Remote Desktop Connection Manager 2.7 from Microsoft that solved my issue.







10-Second SQL Quiz – Select @Var

Do you know the value of variable @Var after this execution? Why? How do you know?

select @Var = StudentName from Students where StudentName like '%ark%'
select @Var


Students Table

StudentID StudentName
1 Peter Parker
2 Harry Potter
3 Tony Stark

REST and Repository, the Perfect Match

A few weeks back, I suddenly realized that REST and Repository was the perfect match in the terms of implementation.

Current popular REST implementations take advantage of HTTP’s header operations such as GET, POST, PUT, DELETE. And the main methods of repository pattern is SELECT, INSERT, UPDATE, DELETE, INSERT.

So we can naturally use REST and Repository together. REST will take care of API interfaces and Repository will manage the backend.

Note: Repository in this discussion is more about the domain layer than data access layer.