A URL Friendly Hash Algorithm

I always try to use GUIDs to identify public resources on a website:

//www.code-overload.co.uk/private/4B979F21-BAEF-46EE-A1E2-B62C114DCFA7

In order for this to work the GUID needs to be persisted, usually in a database. If you can’t persist it, but you need the public ID to be the same for each user/visit, then you can try hashing the private ID. This will generate a non-guessable, repeatable representation of the private ID. The only problem is that hashing usually results in an array of bytes that are not very URL friendly… What I wanted was this:

//www.code-overload.co.uk/private/IMx3Fa3Ds3w9SP6UvNyoseVSee

Here’s a work-around that takes a SHA1 hash, converts the output to Base64, then strips anything that is not a letter or a number. Note – there is an increased chance of hash-collisions, so you need to test it (see unit test below).

private const string SALT = "PUT SOME RANDOM STRING HERE";

/// <summary>
/// Produces a URL friendly hash based on a private ID.
/// </summary>
/// <param name="privateId">The internal (private) ID of the record you want to protected.</param>
/// <returns></returns>
public static string GetUrlFriendlyHash(int privateId)
{
    var saltedString = privateId.ToString() + SALT;
    var temp = Encoding.ASCII.GetBytes(saltedString);

    using (var sha1 = new SHA1Managed())
    {
        var hash = sha1.ComputeHash(temp);	
        var base64 = Convert.ToBase64String(hash);
		
        var filtered = base64
            .Where(x => Char.IsLetterOrDigit(x))
            .ToArray();

        return new string(filtered);
    }
}

Before using this, it’s a good idea to check you don’t get any hash collisions. Here’s a unit test that checks all results are unique up to 1,000,000.

[TestMethod]
public void GetUrlFriendlyHash_Should_Be_Unique()
{
    // Arrange
    var expected = 1000000;
    var dictionary = new Dictionary<string, int>();

    // Act
    for (int i = 0; i < expected; i++)
    {
        var hash = GetUrlFriendlyHash(i);
        dictionary.Add(hash, i);
    }

    // Assert
    Assert.AreEqual(expected, dictionary.Count);
}
Posted in Tips and Tricks | Leave a comment

Using Ellipsis in CSS

It can be a bit tricky getting CSS ellipsis working, so here’s a simple example:

ellipsis

<div class="container">
    <span class="ellipsis">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</span>
    <span class="ellipsis">Aliquam finibus quam eu neque bibendum, vestibulum auctor nisl gravida. Quisque fermentum a eros sed rutrum.</span>
</div>
.container {
    background-color: #CCC;
    width: 300px;
}
.ellipsis {
    display: inline-block;
    -ms-text-overflow: ellipsis;
    -o-text-overflow: ellipsis;
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
    width: 100%;
}

I’ve created a JSFiddle example.

Posted in Reference, Tips and Tricks | Leave a comment

Displaying Validation Errors with ASP.NET MVC

We all know how important it is to validate user input, but it’s equally important how we present validation errors to the user. Take the following form:

email_validation

The email field needs to be optional but any address entered must be valid. If a validation error occurs, it should replace the optional label with the error message.

Behind the scenes I’m using Data Annotations to validate the email address, so any errors will be passed into the ModelState. MVC has built-in support for showing these errors (using the ValidateMessageFor helper) so it’s easy to write a wrapper around that, supplying the ‘optional’ text as a parameter.

Here’s an extension method for the HtmlHelper:

public static class ExtensionMethods
{
    public static MvcHtmlString HelpMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string helpText)
    {
        var validation = htmlHelper.ValidationMessageFor(expression);
        if (validation == null)
            return new MvcHtmlString("<span class='help-inline muted'>" + helpText + "</span>");
        else
            return validation;
    }
}

Here’s it’s usage:

<fieldset>
  <div class="control-group">
        @Html.LabelFor(x => x.EmailAddress, "Email", new { @class = "control-label" })
        <div class="controls">
            @Html.TextBoxFor(x => x.EmailAddress, new { @class = "input-xlarge", placeholder = "Enter an email address" })
            @Html.HelpMessageFor(x => x.EmailAddress, "Optional")
        </div>
    </div>
</fieldset>
Posted in Tips and Tricks | Tagged , , , | Leave a comment

Null Checking Made Easy

It’s fairly common for developers to need to move data from one class structure to another. If the class is complex you may find yourself writing endless null checks to ensure you don’t cause a NullReferenceException:

public PersonSummary CreateSummary(Person person)
{
    var summary = new PersonSummary();
    summary.Name = person.Name;

    if (person.Job != null)
    {
        summary.JobId = person.Job.Id;
        summary.StartDate = person.Job.StartDate;
    }

    if (person.Address != null)
    {
        summary.Street = person.Address.Street;
        summary.Town = person.Address.Town;
    }
    return summary;
}

This article includes a helper function that wraps this null check up so you can perform it in-line:

public PersonSummary CreateSummary(Person person)
{
    return new PersonSummary
    {
        Name = person.Name,
        JobId = GetValueOrDefault(person.Job, x => x.Id),
        StartDate = GetValueOrDefault(person.Job, x => x.StartDate),
        Street = GetValueOrDefault(person.Address, x => x.Street),
        Town = GetValueOrDefault(person.Address, x => x.Town)
    };
}

Here’s a simplified version of the function that just handles strings:

private static string GetString<T>(T model, Func<T, string> selector)
{
    if (model == null)
        return null;
    else
        return selector(model);
}

Here’s a more advanced generic version that handles any type:

private static TResult GetValueOrDefault<T, TResult>(T model, Func<T, TResult> selector)
{
    if (model == null)
        return default(TResult);
    else
        return selector(model);
}

For completeness, here’s the classes from the example:

public class Person
{
    public string Name { get; set; }
    public Job Job { get; set; }
    public Address Address { get; set;  }
}

public class Job
{
    public int Id { get; set; }
    public DateTime StartDate { get; set; }
}

public class Address
{
    public string Street { get; set; }
    public string Town { get; set; }
}

public class PersonSummary
{
    public string Name { get; set; }
    public int JobId { get; set; }
    public DateTime StartDate { get; set; }
    public string Street { get; set; }
    public string Town { get; set; }
}
Posted in Tips and Tricks | Tagged | Leave a comment

How to Deserialize Derived Objects in Json.NET

Imagine you need to process some JSON that looks like this:

{
	"vehicles": [
	{
		"type": "Car",
		"topSpeed": "180mph",
		"engine": "V8"
	},
	{
		"type": "Bike",
		"topSpeed": "20mph",
		"pedal": "Plastic"
	}]
}

Notice how the array contains similar objects, two vehicles. Each vehicle has a “type” property that identifies the specific type of vehicle. If we wanted to deserialize this into C# we could use the following classes:

public class Garage
{
    public List<Vehicle> Vehicles { get; set; }
}

public abstract class Vehicle
{
    public abstract string Type { get; }
    public string TopSpeed { get; set; }
}

public class Car : Vehicle
{
    public override string Type { get { return "Car"; } }
    public string Engine { get; set; }
}

public class Bike : Vehicle
{
    public override string Type { get { return "Bike"; } }
    public string Pedal { get; set; }
}

The challenge is how to tell Json.NET which type to use when deserializing the array. This took quite a bit of Googling on Bing to find the answer:

public abstract class JsonCreationConverter<T> : JsonConverter
{
    protected abstract T Create(Type objectType, JObject jsonObject);

    public override bool CanConvert(Type objectType)
    {
        return typeof(T).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jsonObject = JObject.Load(reader);
        var target = Create(objectType, jsonObject);
        serializer.Populate(jsonObject.CreateReader(), target);
        return target;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

public class VehicleCreationConverter : JsonCreationConverter<Vehicle>
{
    protected override Vehicle Create(Type objectType, JObject jsonObject)
    {
        string typeName = (jsonObject["type"]).ToString();
        switch (typeName)
        {
            case "Car":
                return new Car();
            case "Bike":
                return new Bike();
            default:
                return null;
        }
    }
}

I should point out that this code is not my own. I came upon the code over on StackOverflow, which was a re-post of an earlier StackOverflow question, which led me to the user ‘nonplus’ on the Json.NET discussion boards.

Many thanks to ‘nonplus’, whoever you are!

Posted in Reference | Tagged , | Leave a comment

ASP.NET MVC – Cannot create an instance of an interface

I came across an error message recently that I hadn’t seen before:

postback002

The error occurred when I tried submitting the following form:

postback001

The stack trace suggested it came from the model binder:


[MissingMethodException: Cannot create an instance of an interface.]
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +113
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +232
System.Activator.CreateInstance(Type type, Boolean nonPublic) +83
System.Activator.CreateInstance(Type type) +6
System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) +540

This actually makes a lot of sense. The MVC model binder needs to create an instance of every object in the postback model in order to bind the form values to it. If the postback model contains a property of an interface type (instead of a concrete type) then the model binder won’t be able to create an instance of that property – because it won’t know which concrete type to create, hence the error.

There are several ways to work around this issue, but first let’s review the failing code. The view model contains a list of IPeople which the view loops over, outputting a checkbox for each person in the list. Note that the checkboxes are bound to the IsChecked property on the IPerson interface.

Here’s the HTML with Razor:

@model Blog.Models.PeopleViewModel

<h2>People</h2>
@using(Html.BeginForm())
{
    for (int i = 0; i < Model.People.Count; i++)
    {
        <label class="checkbox">
            @Html.CheckBoxFor(x => Model.People[i].IsChecked) @Model.People[i].Name
        </label>
    }
    <input type="submit" class="btn" />
}

Here’s the code behind:

public class HomeController : Controller
{
    public ActionResult People()
    {
        var model = new PeopleViewModel();
        model.People = new List<IPerson>();
        model.People.Add(new Person { Name = "Dave", IsChecked  = false });
        model.People.Add(new Person { Name = "John", IsChecked  = false });
        model.People.Add(new Person { Name = "Mark", IsChecked  = false });
        return View(model);
    }

    [HttpPost]
    public ActionResult People(PeopleViewModel model)
    {
        // TODO - Do something with the selected items
        return View(model);
    }
}

public class PeopleViewModel
{
    public List<IPerson> People { get; set; }
}

public interface IPerson
{
    bool IsChecked { get; set; }
    string Name { get; set; }
}

public class Person : IPerson
{
    public bool IsChecked { get; set; }
    public string Name { get; set; }
}

The problem could be fixed by moving the IsChecked property from the IPerson interface to the PeopleViewModel (implemented as a list of booleans). My preferred approach is to create a parent view model to contain the property, and have the PeopleViewModel inherit it. This allows the IsChecked property to be re-used on other view models:

public class SelectableViewModel
{
    public List<bool> IsChecked { get; set; }
}

public class PeopleViewModel : SelectableViewModel
{
    public List<IPerson> People { get; set; }
}

Here’s the modified HTML with Razor:

@model Blog.Models.PeopleViewModel

<h2>People</h2>
@using(Html.BeginForm())
{
    for (int i = 0; i < Model.People.Count; i++)
    {
        <label class="checkbox">
            @Html.CheckBoxFor(x => Model.IsChecked[i]) @Model.People[i].Name
        </label>
    }
    <input type="submit" class="btn" />
}

Finally, the IsChecked list needs to be initialized and the POST action needs the type of the model parameter changed from PersonViewModel to SelectableViewModel.

public ActionResult People()
{
    var model = new PeopleViewModel();
    model.People = new List<IPerson>();
    model.People.Add(new Person { Name = "Dave" });
    model.People.Add(new Person { Name = "John" });
    model.People.Add(new Person { Name = "Mark" });

    model.IsChecked = new List<bool> { false, false, false };

    return View(model);
}

[HttpPost]
public ActionResult People(SelectableViewModel model)
{
    // TODO - Do something with the selected items
    return View(model);
}
Posted in Tips and Tricks | Tagged , , | Leave a comment

Wrapping JsonResults in ASP.NET MVC

Like a lot of web developers I like to load page content dynamically but this can cause problems if the Ajax request causes an error on the server. Timeouts can be handled in jQuery but what if the user needs to see more details about the error? This is simple to do if the dynamic content is wrapped inside a JSON object. Here’s an example:

The JSON object I use looks like this:

{
  successful: bool,
  html: string,
  errorMessage: string,
  redirect: string
}

Here’s the JsonResponse class for wrapping the dynamic content.

public class JsonResponse
{
    public bool Successful { get; set; }
    public string Html { get; set; }
    public string ErrorMessage { get; set; }
    public string Redirect { get; set; }

    private JsonResponse()
    { }

    public static JsonResponse Success()
    {
        return Success(null);
    }

    public static JsonResponse Success(string html)
    {
        return new JsonResponse
        {
            Successful = true,
            Html = html
        };
    }

    public static JsonResponse Error(string errorMessage)
    {
        return new JsonResponse
        {
            Successful = false,
            Html = errorMessage
        };
    }

    public static JsonResponse RedirectTo(string url)
    {
        return new JsonResponse
        {
            Successful = true,
            Redirect = url
        };
    }
}

Here’s an example of returning the object from a controller action:

public class HomeController : Controller
{
    [HttpPost]
    public JsonResult SuccessTest()
    {
        return Json(JsonResponse.Success("<p>All done!</p><br />"));
    }

    [HttpPost]
    public JsonResult RedirectTest()
    {
        return Json(JsonResponse.RedirectTo("/another/page"));
    }

    [HttpPost]
    public JsonResult ErrorTest()
    {
        return Json(JsonResponse.Error("Something went wrong"));
    }
}

How can you return a view?

Ion Drimba has written an excellent article on how to render a view as a string. His article can be found here.

What if the request times-out?

An Ajax timeout is easy to detect using jQuery. Here’s an example with a 30 second timeout which uses also assumes the use of the JsonResponse wrapper:

$.ajax({
    type: "POST",
    url: '/basket/buy',
    data: data,
    timeout: 30000,
    success: function (response) {
        if (response.Successful)
            window.location.href = response.Redirect;
        else
            // TODO: Show an error using response.ErrorMessage
    },
    error: function (request, status, err) {
        if (status === "timeout")
            toastr.error('There was a timeout');
        else
            toastr.error('There was a problem retrieving your results');
    }
});

Can the JavaScript properties be Camel Cased?

While the examples above don’t require this, it’s nice to have the JavaScript properties appear as Camel Case. ASP.NET MVC doesn’t do this by default so here’s a link to help.

Displaying toast notifications

John Papa and Hans FjÀllemark have created an excellent JavaScript script for displaying UI toast notifications for Success, Error and Information. The Nuget page for ‘toastr’ can be found here.

Posted in Reference, Tips and Tricks | Tagged , , , | Leave a comment