Make a QR Code Easily in ASP.NET Web Forms and MVC

This post covers how, in 8 lines of code, you can write a custom HttpHandler to easily generate QR codes from client-side code. (Demo project on Github)

My previous post explains how to use a custom HTML Helper in ASP.NET MVC to create easy, on-the-fly QR codes. This is great for some scenarios, but it just doesn't work well in other cases.

What if you want to display QR codes for URLs you received in JSON via an AJAX call? What if you are using ASP.NET Web Forms and want an easy way to create a QR code? In my specific case, I needed to show QR codes in a repeating, client-side template built in Angular.js.

I wanted the QR Code generation to be easy, and I didn't want to save generated code images on the server. How easy was it? In the end, when I need a QR code, all it takes is this:

<img src="uselessname.qr?u=UrlToTurnIntoQR">
or
<img src="myqr.qr?u=http://www.mikesmithdev.com" alt="Yes, this is a QR Code">

Did you just set the image source to .qr?? What is that?

Read on.

The idea is simple: Set the src of the img to a custom file type that is handled by the HttpHandler we are going to write, passing in the URL to be shortened in the query string. Yeah. Simple. So let's start:

(If you've read my previous post, The Easiest Ways To Fail at QR Codes, you'll know I'm not a QR code evangelist... but hey, sometimes they have their purpose...)

Step 1. Install the ZXing.Net Nuget Package

This does most of the hard work. Ok, it does pretty much all of the hard work. Just go to your package manager console and install it:

PM> Install-Package ZXing.Net

Step 2. Create a HttpHandler to Process and Generate the QR Code

HTTP handlers are ASP.NET components that run when they are requested and return dynamically created information. In an older post, I show how to use one to secure and log downloads for PDF files.

Right-click your project -> Add New Item -> Generic Handler

I named mine QRHandler.ashx

using System;
using System.Drawing.Imaging;
using System.IO;
using System.Web;
using ZXing;
using ZXing.Common;

namespace YourSite
{
    /// <summary>
    /// Converts the "u" querystring in a ".qr" image to a qr code
    /// Example use: img src="test.qr?u=http://www.google.com"
    /// </summary>
    public class QRHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            //begin the 8 lines o' magic
            string urlToQRify = context.Server.UrlDecode(context.Request.QueryString["u"]);
            var qrWriter = new BarcodeWriter();
            qrWriter.Format = BarcodeFormat.QR_CODE;
            qrWriter.Options = new EncodingOptions() {Height=500, Width=500, Margin=0};
            //I like to make them large. You can resize them with CSS later
            using (var bitmap = qrWriter.Write(urlToQRify))
            {
                using (var stream = new MemoryStream())
                {
                    context.Response.ContentType = "image/png";
                    bitmap.Save(context.Response.OutputStream, ImageFormat.Png);
                }
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

Step 3: Update the web.config to define that new .qr file type

IIS doesn't like to serve up file-types that it doesn't know. So, let's tell it to serve up .qr as a .png.

<system.webServer>
    <staticContent>          
        <remove fileExtension=".qr" />
        <mimeMap fileExtension=".qr" mimeType="image/png" />
        ...
    </staticContent>

Step 4: Update the web.config to use your new handler

This is how we tell ASP.NET to process the .qr extension and not try to treat it as a static file-type, which would normally bypass the ASP.NET pipeline and just be handled by IIS.

<system.webServer>
    <handlers>
        <add name="QRHandler" type="YourSite.QRHandler" path="*.qr" verb="GET"  />
        ...
    </handlers>

Step 5: Ensure your routes ignore .qr

This is for ASP.NET MVC routing. You probably won't need this in Web Forms. Ensure .qr gets ignored, so update your RouteConfig:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.qr");

That is it! Now whenever you set an src of an img to a .qr file-type, the HttpHandler will jump in, generate the QR code, and send it back to the browser. I successfully used this in a ng-repeat in an angular.js template in a ASP.NET MVC project like this:

<img ng-src="{{url.id}}.qr?u={{ url.RedirectURL }}" />

And the cool part it, as I edit the model and change url.RedirectURL, the QR Code live-updates as well.

Leave questions in the comments!