QR code MVC html helper

Display runtime generated QR code in MVC page

  • Share

This article is based on one of my previous topic Advanced Base64 image extension in ASP.NET MVC. It uses the same concept to display image on the page and to cache it, but it involves QR code bitmap generation which is basically a NuGet package use.

Basically, QR code is generated using NuGet package QRCoder https://www.nuget.org/packages/QRCoder/ and result Bitmap is serialized to base64 string and cached so we do not regenerate same QR bitmap over and over on every request which may lead to server overload.

using QRCoder;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Mvc.Razor.Helpers
{
    public static class Extensions
    {
        public static MvcHtmlString QRCode(this HtmlHelper htmlHelper, String value, Color darkColor, Color lightColor, 
            QRCodeGenerator.ECCLevel correctionLevel = QRCodeGenerator.ECCLevel.Q, int pixelPerModule = 3, IDictionary<String, String> attributes = null)
        {
            var context = HttpContext.Current;
            var builder = new TagBuilder("img");
            String cacheKey = value;
            String cachedContent = context.Cache.Get(cacheKey) as String;

            if (attributes != null && attributes.Any())
            {
                foreach (var attribute in attributes)
                {
                    builder.Attributes.Add(attribute.Key, attribute.Value);
                }
            }

            if (cachedContent == null)
            {
                using (QRCodeGenerator qrGenerator = new QRCodeGenerator())
                {
                    using (QRCodeData qrCodeData = qrGenerator.CreateQrCode(value, correctionLevel))
                    {
                        using (QRCode qrCode = new QRCode(qrCodeData))
                        {
                            using (Bitmap qrCodeImage = qrCode.GetGraphic(pixelPerModule, darkColor, lightColor, true))
                            {
                                using (var stream = new MemoryStream())
                                {
                                    qrCodeImage.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
                                    String srcTemplate = "data:image/png;base64,{0}";
                                    cachedContent = string.Format(srcTemplate, Convert.ToBase64String(stream.ToArray()));
                                    context.Cache.Insert(cacheKey, cachedContent, null, DateTime.MaxValue, TimeSpan.FromHours(1));
                                }
                            }
                        }
                    }
                }
            }
            builder.Attributes["src"] = cachedContent;
            return MvcHtmlString.Create(builder.ToString());
        }
    }
}

    

You must not forget to reference the namespace in your Web.config file in Views folder in order to use this HTML helper:

  <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Optimization"/>
        <add namespace="System.Web.Routing" />
        <add namespace="Mvc.Razor.Helpers" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>
    
    

Once this is done you can invoke this helper as a part of your Razor view

@Html.QRCode("http://yahoo.com", Color.Blue, Color.White)
    

QRCoder NuGet package exposes some more options like correction level and and number of pixels per module which are also exposed by HTML helper.

Last optional parameter of the helper are custom attributes which are basically HTML attributes which will be on the generated tag.

  • Share

Disclaimer

Purpose of the code contained in snippets or available for download in this article is solely for learning and demo purposes. Author will not be held responsible for any failure or damages caused due to any other usage.

Comments for this article

comments powered by Disqus