I had a task of creating a QR barcode and displaying it on a web-page from ASP.Net MVC system. There are a lot of free web-services for generating a qr-codes for you, ( like http://qrcode.kaywa.com/ ) But this time I did not want to use a service for various reasons. I had to get the barcode generated on my server. (Just accept it as default!)

I have found many .Net libraries that generate a qr-barcodes, but for some reason I did like QrCode.Net. Probably because it is hosted on codeplex and I keep my open-source projects there as well.

I have downloaded their Dll file, added it as a reference to my MVC project:

In my MVC project I have added a new action that returned a FileStremResult:

using Gma.QrCodeNet.Encoding;
using Gma.QrCodeNet.Encoding.Windows.Controls;

public virtual FileResult BarcodeImage(String barcodeText)
{
    // generating a barcode here. Code is taken from QrCode.Net library
    QrEncoder qrEncoder = new QrEncoder(ErrorCorrectionLevel.H);
    QrCode qrCode = new QrCode();
    qrEncoder.TryEncode(barcodeText, out qrCode);
    Renderer renderer = new Renderer(5, Brushes.Black, Brushes.White);

    // write to file if required for auditing
    //renderer.CreateImageFile(qrCode.Matrix, String.Format(@"d:\tmp\{0}.png", barcodeText), ImageFormat.Png);

    Stream memoryStream = new MemoryStream();
    renderer.WriteToStream(qrCode.Matrix, memoryStream, ImageFormat.Png);

    // very important to reset memory stream to a starting position, otherwise you would get 0 bytes returned
    memoryStream.Position = 0;

    var resultStream = new FileStreamResult(memoryStream, "image/png");
    resultStream.FileDownloadName = String.Format("{0}.png", barcodeText);

    return resultStream;
}

UPDATE 23 Dec 2013: Since this article was written, the API of QrCode.Net has changed slightly and the code above does no longer compile. So see the new code:

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Web.Mvc;
using Gma.QrCodeNet.Encoding;
using Gma.QrCodeNet.Encoding.Windows.Render;

namespace SampleBarCodeMvc.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult BarcodeImage(String barcodeText)
        {
            // generating a barcode here. Code is taken from QrCode.Net library
            QrEncoder qrEncoder = new QrEncoder(ErrorCorrectionLevel.H);
            QrCode qrCode = new QrCode();
            qrEncoder.TryEncode(barcodeText, out qrCode);
            GraphicsRenderer renderer = new GraphicsRenderer(new FixedModuleSize(4, QuietZoneModules.Four), Brushes.Black, Brushes.White);

            Stream memoryStream = new MemoryStream();
            renderer.WriteToStream(qrCode.Matrix, ImageFormat.Png, memoryStream);

            // very important to reset memory stream to a starting position, otherwise you would get 0 bytes returned
            memoryStream.Position = 0;

            var resultStream = new FileStreamResult(memoryStream, "image/png");
            resultStream.FileDownloadName = String.Format("{0}.png", barcodeText);

            return resultStream;
        }
    }
}

Then in one of the views I place this image tag:

  <img src="/Controller/BarcodeImage?barcodeText=Hello"/>

Where Controller is a name of your controller where you placed the action. And that will give you an image with a barcode and word “Hello” encoded in it.

I have quickly created a sample solution in Visual Studio 2013 (you should be able to open that in VS2012):
SampleBarCodeMvc – this is to show a working example.

Enjoy!

Update: QrCode.Net is now available via nuget package and can be installed either via Nuget inside of your Visual Studio or in VS-console: Install-Package QrCode.Net

SampleBarCodeMvc
Title: SampleBarCodeMvc (0 click)
Caption:
Filename: samplebarcodemvc.zip
Size: 10 MB

Sometimes you just don’t want a validation on your form elements, but the framework just adds the validation automatically, cause it is too clever. To disable the validation on one element, pass html parameter data_val=false to your controller and JavaScript will ignore the that field. Example:

@Html.DropDownList("documentId", new SelectList(ViewBag.MetaTags, "Value", "Text"), new {data_val=false})

Sometimes you need to show date in a “Due in X-days” format, not just a date. This will convert date to a string with granularity: Today, tomorrow, yesterday, days, weeks, months.

public static class HumanTime
{
    public static string DueDate(DateTime dueDate) {
        return DueDate(dueDate, DateTime.Now);
    }

    public static string DueDate(DateTime dueDate, DateTime dateNow) {
        DateTime nowDate = dateNow;

        TimeSpan ts = nowDate - dueDate;

        if (dueDate.Date == DateTime.Today)
        {
            return "due today";
        }

        if (dueDate.Date == DateTime.Now.AddDays(1).Date)
        {
            return "due tomorrow";
        }

        if (dueDate.Date == DateTime.Now.AddDays(-1).Date)
        {
            return "was due yesterday";
        }


        int totalDays = (int)Math.Round(ts.TotalDays);
        if (Math.Abs(totalDays) &lt; 7)
        {
            return DueStringFormat(totalDays, "day");
        }

        int weeks = (int)Math.Round( ts.TotalDays / 7 );
        if (Math.Abs(weeks) &lt; 5 && Math.Abs(totalDays)&lt;30 )
        {
            return DueStringFormat(weeks, "week");
        }

        int months = (int)Math.Round( ts.TotalDays / 30 );
        return DueStringFormat(months, "month");
    }


    public static string DueStringFormat(int count, string unit)
    {
        string format = "{0} {1}";
        if (count &lt; 0)
        {
            format = "due in {0} {1}";
        } 
        else
        {
            format = "{0} {1} overdue";
        }

        return String.Format(format, Math.Abs(count), unit.Quantify(count));
    }


    /// Adds "s" suffix to a word if there are more than one thing involved.
    public static string Quantify(this String singular, int count)
    {
        int abs = Math.Abs(count);
        if (abs > 1)
            return singular+"s";
        else 
            return singular;
    }
}

Enums are handy. But they do not allow you have easy Text description on them.
How about using DisplayAttribuite on enum values and have that text in a drop-down? Easy!

/// <summary>
/// Creates a SelectList from Enum, taking Description values from Enum fields
/// Taken from here: http://stackoverflow.com/a/3705387/809357
/// </summary>
public static SelectList ToSelectListWithDisplayName<T>(this T enumeration, string selected = "")
{
    var source = Enum.GetValues(typeof(T));

    var items = new Dictionary<object, string>();

    var displayAttributeType = typeof(DisplayAttribute);

    foreach (var value in source)
    {
        FieldInfo field = value.GetType().GetField(value.ToString());

                    if (field == null) continue;

        DisplayAttribute attrs = (DisplayAttribute)field.GetCustomAttributes(displayAttributeType, false).FirstOrDefault();
        if (attrs != null)
        {
            items.Add((int)value, attrs.GetName());
        }else   // in case Description attribute is not available, we fall back to the default name
        {
            items.Add((int)value, value.ToString());
        }
    }
    return new SelectList(items, "Key", "Value", selected);
}

Also you can get just on Display Name for one Enum Value:

public static string GetDisplayName(this Enum value)
{
    FieldInfo field = value.GetType().GetField(value.ToString());

    if (field == null)
        return String.Empty;

    object[] attribs = field.GetCustomAttributes(typeof(DisplayAttribute), true);
    if(attribs.Length > 0)
    {
        return ((DisplayAttribute)attribs[0]).GetName();
    }
    return value.ToString();
}

Creating custom attribute is pretty simple really, just follow the example. You need to return MvcHtmlString – that is string with your html to be displayed on a page – this will not be escaped.

public static MvcHtmlString DisplayWithNameFor<TModel, TProperty>(
    this HtmlHelper<TModel> htmlHelper,Expression<Func<TModel, TProperty>> expression)
{
    ModelMetadata metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
    if (metaData.Model == null)
    {
        return MvcHtmlString.Create(String.Empty);
    }

    string html = "<div class=\"display-label\">";
    html += htmlHelper.LabelFor(expression).ToString();
    html += "</div><div class=\"display-field\">";
    html += htmlHelper.DisplayFor(expression).ToString();
    html += "</div>";

    return MvcHtmlString.Create(html);
}

Whenever you need a page to return to the previous page when you get an form submit or some other action, this can be used:

Have a base controller that is inherited by all your controllers. That is always a good idea – you can easily add things that work site-wide.
In you base controller have a OnActionExecuting overriden – here we are going to store the previous page.
Something like this:

public abstract partial class MyController : Controller
{

public ActionResult RedirectToPrevious(String defaultAction, String defaultController)
{
  if (Session == null || Session["PrevUrl"] == null)
  {
      return RedirectToAction(defaultAction, defaultController);
  }

  String url = ((Uri)Session["PrevUrl"]).PathAndQuery;

  if (Request.Url != null && Request.Url.PathAndQuery != url)
  {
      return Redirect(url);
  }

  return RedirectToAction(defaultAction, defaultController);
}


protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var httpContext = filterContext.HttpContext;

    if (httpContext.Request.RequestType == "GET"
        && !httpContext.Request.IsAjaxRequest()
        && filterContext.IsChildAction == false)    // do no overwrite if we do child action.
    {
        // stop overwriting previous page if we just reload the current page.
        if (Session["CurUrl"] != null 
            && ((Uri)Session["CurUrl"]).Equals(httpContext.Request.Url) ) 
            return;

        Session["PrevUrl"] = Session["CurUrl"] ?? httpContext.Request.Url;
        Session["CurUrl"] = httpContext.Request.Url;
    }
}
}

Now, as I figured, it is not the best idea for redirecting everything by default. For validation purposes you would like not to redirect

Then you can reference Session[“PrevUrl”] in controllers, but there is a better way of doing it – create attribute!

public class RedirectToPreviousPageAttribute : ActionFilterAttribute
{
///

/// Place [RedirectToPreviousPage] attribute on Controller action
/// and when you do submit of form, this functionality will kick in.
/// We check if Session has Previous URL set and force to redirect
/// to whatever it says.
/// If no Session variable is set, just do what it is supposed to do in the first place.
///

/// public override void OnResultExecuted(ResultExecutedContext filterContext)
{
var httpContext = filterContext.HttpContext;

    if (httpContext.Session == null || httpContext.Session["PrevUrl"] == null)
    {
        base.OnResultExecuted(filterContext);
        return;
    }

    String url = ((Uri)httpContext.Session["PrevUrl"]).PathAndQuery;

    if (httpContext.Request.Url != null && httpContext.Request.Url.PathAndQuery != url)
    {
        httpContext.Response.Redirect(url);
    }


    base.OnResultExecuted(filterContext);

}

}

And now, wherever you are put this attribute on a controller action (or entire controller), it will redirect to the previous page:

[HttpPost]
public virtual ActionResult Edit(Model model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    _repository.InsertOrUpdate(model);
    _repository.Save();

    return RedirectToPrevious("Index", "Controller");
}

VoilĂ ! Good to go!