Retrieving Data From Collections/Enumerables Safely in .NET

Background

While developing any sort of application, we are almost always dealing with some sort of collection or enumerable data structure and we are almost always using LINQ to query it. It’s such a common aspect of coding that working with them has become second nature and at times it can be easy to forget best practices when using them. The most commonly forgotten best practice being the safe retrieval of data contained within them.

The Problem

Let’s say we have the following code:

var myList = new List<string>();

// Do stuff to add items to myList

var firstItem = myList.First();

var allUppercase = firstItem.ToUpper();

Console.WriteLine(allUppercase);

Do we see an issue here? What happens if myList.First(); is empty? Calling myList.First(); on an empty list will lead to an InvalidOperationException. BOOM our code is broken.

The Solution

The first aspect we need to consider is whether or not the collection will ever be empty. If you know for sure that it never will be, then calling myList.First(); isn’t a huge deal (but we should still check to see if the item it returns is null before using it).

The next aspect to consider is how you are using First(). What I mean is, if we have the following code:

var myList = new List<string> { "myItem" };

var firstItem = myList.First();

var allUppercase = firstItem.ToUpper();

Console.WriteLine(allUppercase);

calling myList.First(); isn’t a big deal because there is at least one item in the list. But what if we have the following code?

var myList = new List<string> { "myItem" };

var firstItem = myList.First(item => item == "otherItem");

var allUppercase = firstItem.ToUpper();

Console.WriteLine(allUppercase);

This is going to throw an InvalidOperationException becuase myList does not contain a string that is equal to otherItem.

So how do we solve this? Simple, we use FirstOrDefault() which will either return the first item or the default value of the type the collection/enumerable contains if the collection/enumerable is empty or there are no items matching your predicate.

var myList = new List<string>();

var firstItem = myList.FirstOrDefault();

if (firstItem != default(string))
{
	var allUppercase = firstItem.ToUpper();

	Console.WriteLine(allUppercase);
}

The above code covers both cases we’ve described in the problem safely! If myList is empty, we receive the default value of string (which is null). If we were to pass the same predicate in the previous example where we are looking for the first string that matches otherString, then again, we will receive the default value of string. We then check to see if we received the default value, and if not, we know we have a value and we can do something with it 🙂

TL;DR

When using collections and enumerables in .NET we should take the following steps:

  • First, determine if the collection/enumerable could ever be empty. If so, use FirstOrDefault().
  • Next, determine if the collection will ALWAYS have at least one member. If not, use FirstOrDefault().
  • Next, if you are using a predicate to filter the collection/enumerable, determine if your predicate would have the potential to not find a match. If so, use FirstOrDefault(predicateHere).
  • If the collection/enumerable will NEVER be empty and will ALWAYS have at least one value, and if you are using a predicate, will ALWAYS match the predicate you are using, then you can use First() (but you should always ALWAYS check if the item is equal to it’s default value. E.g. if(firstItem == default(string)){ }). But… I would still probably use FirstOrDefault() anyway (unless you really want that tiny micro-optimization of First()).

Checkout my GitHub: https://github.com/StephenMP

Simplifying Model Validation in ASP.NET Core Projects

Background

When developing an ASP.NET Core Web Application or Web API project, one task we perform quite often is model/object state validation. We like to make sure that what we are receiving is what we are expecting, right? Of course! That’s what writing good code is about! If we are going to extend functionality to someone or something to use, we should always ensure that the way in which our functionality is used, is a way in which we expect it to be used.

The downside here, however, is that validating our object state is plagued by one of the most annoying aspects to writing/reading code… verbose code that essentially does the same thing, but is hard to abstract out to a method.

The Problem

So we have the background, but what does this mean? Well, suppose we have the following code:

[HttpPost]
public IActionResult SomePostMethod([FromBody] SomeModel someModel)
{
    //Do something with someModel

    return Ok();
}

where SomeModel is defined as:

public class SomeModel
{
    // Must not be null or whitespace
    public string SomeString { get; set; }

    // Must be greater than 0
    public int SomeInt { get; set; }
}

We want to be good developers, so we want to make sure that someModel is valid (i.e. that it is not null and that all the members in it are not null and have a value). So we do it as follows:

[HttpPost]
public IActionResult SomePostMethod([FromBody] SomeModel someModel)
{
    if(someModel == null)
    {
        return BadRequest("{nameof(someModel)} was null");
    }

    if (string.IsNullOrEmpty(someModel.SomeString))
    {
        return BadRequest("{nameof(someModel.SomeString)} was null or empty");
    }

    if(someModel.SomeInt <= 0)
    {
        return BadRequest($"{nameof(someModel.SomeInt)} was less than or equal to 0");
    }

    //Do something with someModel

    return Ok();
}

Okay, cool. We’ve validated our object, but look how long and verbose that validation checking is! It’s easy to think something like “But… what if you put all the if checks into one if statement using OR logic?”. It is correct that this reduces lines of code, but it does not reduce the amount of typing and checking involved (plus, you lose your ability to have very specific error messages).

So, now we have validation, but we don’t like it because it’s too verbose. Then it hits us! We remember that .NET has some built in validation for controller methods which uses the ModelStateDictionary and we can use Data Annotations to make validation easy! So, we rewrite SomeModel as follows:

public class SomeModel
{
    [Required]
    public string SomeString { get; set; }

    [Range(1, int.MaxValue)]
    public int SomeInt { get; set; }
}

and we rewrite our code as follows:

[HttpPost]
public IActionResult SomePostMethod([FromBody] SomeModel someModel)
{
    // Still have to check if this is null as
    // ModelState allows ActionArguments to be null
    if(someModel == null)
    {
        return BadRequest($"{nameof(someModel)} was null");
    }

    if (!ModelState.IsValid) {
        return BadRequest(ModelState);
    }

    //Do something with someModel

    return Ok();
}

Awesome! This is a lot cleaner and way more simple. The downside here though, is that we always have to check if the model being passed in is null or not because the model state validation allows action arguments to be null. Plus, every controller method is going to have at least two similar if checks which is going to cause your controller methods to look pretty cluttered.

The Solution

So what do we do then? It’s as simple as it can get, right? Wrong! What if I told you that we can perform the above validation without writing a single if check in our controller methods? Would you believe me? Well, guess what… we can perform the above validation without writing a single if check in our controller methods! Even better, it’s extremely simple to do.

First, in order to do this, we are going to be using an ActionFilterAttribute. If you are unsure of what Attributes or Filters are, you should check out this article. We begin by creating a class that inherits from the ActionFilterAttribute class:

[AttributeUsage(AttributeTargets.Method)]
public sealed class ValidateModelStateAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        // First, check all action arguments and make sure they aren't null
        foreach (var argument in context.ActionArguments)
        {
            if (argument.Value == null)
            {
                context.ModelState.AddModelError(argument.Key, $"{argument.Key} cannot be null");
            }
        }

        // Now we check if the model stat is valid. The IsValid property
        // Checks to see if any erros have been added to the ModelState
        // Since we add an error if any action arguments are null, this
        // Would be true if we found any. It will also be true if the
        // Supplied model to the controller failed validation from data
        // Annotations.
        if (!context.ModelState.IsValid)
        {
            context.Result = new BadRequestObjectResult(context.ModelState);
        }
    }
}

We then use our new filter as follows:

[HttpPost]
[ValidateModelState]
public IActionResult SomePostMethod([FromBody] SomeModel someModel)
{
    //Do something with someModel

    return Ok();
}

Wow! That really cleaned up our controller method! The best part though, is now if we want this validation on any method, we just add our filter to the method and BAM! We have object state validation. You could even go as far as putting the filter on a class level, or even add it into your global filters on startup. I personally stray away from this because not every controller method is going to need this validation, so I add it specifically to the ones that do.

TL;DR

We can simplify our object state validation by using Data Annotations and a custom action filter. You can checkout a complete, working example on my GitHub

Checkout my GitHub: https://github.com/StephenMP

Hello World

Introduction

Well, hello there. I guess I should throw out a little intro to this blog and give some context as to what you can expect from this blog. I wanted to start a blog as a simple outlet for my own thoughts, ideas, implementations, advice, etc. Whether or not it ever gets any views from anyone other than myself, who knows, but at least the content is out there for anyone to stumble upon.

Overview

My goal for this blog is exactly as the title indicates. I want this to be a “Life Blog” where I share all things life related that I am passionate about. Primarily, these things will be technology, fitness/nutrition, and personal finance related, but they are definitely not limited to just those.

Final Message

I hope you enjoy the content you find here and find at least some of it useful!

Checkout my GitHub: https://github.com/StephenMP