Sunday 3 May 2015

An Accessible Validation Summary for ASP.NET MVC Applications

This blog post relates to WCAG Criteron 3.3.1 - identifying input errors to non-sighted and partially sighted users, and in particular, Guideline G139 - Creating a mechanism that allows users to jump to errors.

NuGet package

Github source code

As mentioned in a previous post, accessibility is an issue that I have lacked awareness of in the past, but has featured heavily on my radar in a recent project. Forms on ASP.NET MVC applications commonly supply a validation summary to list validation errors on submission of a form. The standard validation summary does not conform with WCAG Criterion 3.3.1, because the summary does not alert screen reader user to the presence of the errors, and it does not provide links to allow the user to jump directly to the field that is the source of the error.

Once you have added the package from Nuget, add these links to your page (or add them through Bundle):

<link href="/Content/lucidity.accessible.validation.mvc.css" rel="stylesheet"/>
<script src="/Scripts/lucidity.accessible.validation.mvc.js"></script>

and in your views, replace the usual

@Html.ValidationSummary(true, "", new { @class = "text-danger" })

with

@Html.Partial("_ValidationSummary", Html.ViewData.ModelState)

and that is all you need to be up and running.

The JavaScript file is to handle client side validation, and the _ValidationSummary partial is to handle it server side (Although the partial is also used as the template for the client side). The first point to note is the inclusion of role="alert" on the heading of the _ValidationSummary partial. As soon as this becomes visible, the screen reader is alerted to it. Focus is placed on the title so the user can then navigate to the next link. When return, space bar or the usual screen reader select key is pressed, focus is then passed directly to the related control.

Saturday 11 April 2015

An Updated Template For Enterprise Applications

My template that forms the architectural basis for many of my projects is continuously improved as my knowledge and experience increases. The latest version contains many of the patterns and practices that I have been using over the last year or so.

The code for this post can be found here on Github.

Overview

In fact, this is not so much of a template but more of a sample application. It is based on a camper van rental company (anyone one who knows me will know that this is something I briefly dabbled with before concluding my future actually did lie with software development after all). There is a front end for hiring, and a back end for logging pick ups, drop offs and maintenance.

Architecture

The Domain Model still forms the basis of what I do, and while I am constantly on the lookout for alternatives when circumstances dictate, I still find that most of the time it is the default solution.

One change is that I have abandoned the Application layer (sometimes called the Service layer). I could no longer justify having this layer in code. The purpose of this layer was simply to load entities from repositories, call the business logic contained in the entities and then save them. The problem is that this just became another layer for business logic to seep into from the domain. This functionality now sits in the controller of the UI. Some may argue that this violates the Single Responsibility Principle, but pragmatism wins over ideology here. It only adds a couple of lines of code to the controller and ultimately leads to more maintainable code, which is more important than religiously adhering to design principles.

Design

Here is a use case diagram of the functionality included:

Security

I have used ASP.NET Identity, but at arms length. Authentication, including storage of the UserProfile, password encryption and cookie management is handled by ASP.NET Identity. However details about the user are stored within the domain model, and store a reference key to the ASP.NET Identity UserProfile. This is because the UserProfile object must inherit IdentityUser, therefore meaning the Domain would have to have a reference to Microsoft.AspNet.Identity.EntityFramework. My Domain references look like this:

Image demonstrating how domain only has references to System and System.Core

and I want it to stay that way. What's worse, this dependency propagates through the entire project. Most of the assemblies end up needing a reference to it - not great. Also I like to keep my role/permission management within the Domain, as sometimes permissions are intertwined with business logic, as explained here.

Also, I have been working my way through the OWASP Top Ten, but this is far from complete. I will be blogging about these issues in future posts.

Accessibility

Another area that my work has been focusing on recently is the much forgotten area of accessibility, and in particular, the tailoring of websites for screen readers. There is barely a website on the internet that does not fall down in some way on this, partly down to lack of priority, but mainly due to lack of awareness. Also the technology is inconsistent and sometimes unreliable, and when you consider that instead of having to support x number of browsers, you are now supporting x number of browsers multiplied by y number of screen readers, you can begin to see the challenge. However, we have a moral duty to accommodate non-sighted users, and sooner or later, we will have a legal one (the physical domain have accessibility laws in the form of building regulations, so you can be sure that the digital domain will do soon as well).

The Web Content Accessibility Guidelines (WCAG) 2.0 are the accepted accessibility standards, and where possible, I have adhered to these. Of particular note is the accessible form validation summary, which will feature its own blog post in the future.

Thursday 19 February 2015

Why You Should Have One ViewModel Per View

A classic rule to ahere to in MVC is to have a one-to-one relationship between Views and ViewModels. Sometimes it is tempting to share ViewModels between Views in the name of efficiency, but the long term costs will outweigh any short term gains. The following is an explanation of one such situation.

As always, the code in this example has been recreated to illustrate the issue under discussion. I never post any of my client's code. This is a simplified version of the actual situation.

The Problem

Recently I had to modify an ASP.Net MVC Razor View that listed a Customers. The View resembled this:

@using Lucidity.SampleSystem.Enumerations
@model IEnumerable<Lucidity.SampleSystem.ViewModels.CustomerSummaryViewModel>

@{
    ViewBag.Title = "Customers";
}

<h2>Customers</h2>

<table>
    <tr>
        <th>
            Customer
        </th>
        <th>
            Registered On
        </th>
        <th>
            Contract Value
        </th>
        <th></th>
    </tr>

@foreach (var customer in Model) {

    string customerDescription = null;

    if (customer.Type == CustomerType.Individual)
    {
        customerDescription = 
            customer.Title + " " + 
            customer.GivenName + " " + 
            customer.FamilyName;
    }
    else if(customer.Type == CustomerType.Corporate)
    {
        customerDescription = customer.CompanyName;
    }
    
    <tr>
        <td>
            @customerDescription
        </td>
        <td>
            @Html.DisplayFor(modelItem => customer.RegisteredOn)
        </td>
        <td>
            @Html.DisplayFor(modelItem => customer.ContractValue)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", 
                new { id = customer.Id }, 
                new { aria_label = "Edit " + customerDescription }) |
            @Html.ActionLink("Details", "Details", 
                new { id = customer.Id }, 
                new { aria_label = "Details for " + customerDescription }) |
            @Html.ActionLink("Delete", "Delete", 
                new { id = customer.Id }, 
                new { aria_label = "Delete " + customerDescription })
        </td>
    </tr>
}

</table>

SyntaxHighlighter is doing some funny things here - this is best viewed in plain text.

This offending code lies between lines 26 and 38. The issue is the presence of logic in the View. This is bad practice for numerous reasons:

  • This is not how ASP.Net MVC is intended to be used, and so causes confusion for future maintainers of the code.
  • The View is difficult to test. Yes, there are options, but it is far simpler for this logic to be in a ViewModelFactory, and for that to be unit tested. And in the case of testing, if it's simpler, it's more likely to be done.
  • There are already various places for logic to be spread around, rightly or wrongly (Domain, ViewModelFactory, Controller). We don't need another one.

Why was This Decision Made?

So why would a developer have done this? It does not appear to be the work of an incompetent or complacent developer.

The rest of the code base would suggest that the team had a good grasp of ASP.Net MVC, and would have known this was not standard practice.

One thing that caught my eye was the @model for the View:

@model IEnumerable<Lucidity.SampleSystem.ViewModels.CustomerSummaryViewModel>

It doesn't look like this ViewModel has been designed specifically for this View. In fact, it is used on a PartialView called _CustomerSummary that is displayed at the top of many of the pages.

Standard practice would be for this sort of logic calculation to be performed in a ViewModelFactory, and set a field in the ViewModel. What is odd is that a field called 'Description' does actually exist in the ViewModel:

namespace Lucidity.SampleSystem.ViewModels
{
    public class CustomerSummaryViewModel
    {
        public Guid Id { get; set; }
        public string Title { get; set; }
        public string GivenName { get; set; }
        public string FamilyName { get; set; }
        public string CompanyName { get; set; }
        public CustomerType Type { get; set; }
        public DateTime RegisteredOn { get; set; }
        public decimal ContractValue { get; set; }
        public string Description { get; set; }
    }
}

However, this field was already being set in a ViewModelFactory for the _CustomerSummary View, but it's just a simple concatenation - no logic to display CompanyName for corporate customers.

The Background Cause

When the requirement came for a list of customers, a design decision was made to reuse the CustomerSummaryViewModel for the new View. This would have seemed like a good idea at the time: The fields to be displayed in the Customer list were just a subset of those displayed in the CustomerSummary. The Description field was always the same for both. So the new View was bound to the existing ViewModel, and the new controller used the Existing ViewModelFactory to generate the ViewModel from the list of Customer entities. A search through the source control history confirms this - the requirements were once aligned.

The problem with this approach comes when the a change is requested for either of the Views that are bound to that ViewModel. In this case, a new requirement was raised for the Company name to be displayed for corporates. Where does this new logic go? The ViewModelFactory doesn't know if it is creating a CustomerSummaryViewModel for _CustomerSummary or the Index. It would have been possible, perhaps, to pass in a flag to the ViewModelFactory, telling it what it was creating it for, and it could then make a decision accordingly. But it is likely time constraints caused the developer to take this approach.

We are all capable of hacky behaviour like this, if pushed down a dead end and when the pressure's on. The trick is not to push oursleves or our fellow develeopers into such dead ends. Keeping to the rule of one View per ViewModel is one such way of avoiding such dead ends.

Sources

http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/ http://lostechies.com/jimmybogard/2013/07/17/how-we-do-mvc-4-years-later http://stackoverflow.com/questions/9413034/viewmodel-per-view-or-per-model