.NET Best Practices and Tips by Toptal Developers

This resource contains a collection of .NET best practices and tips provided by our Toptal network members. As such, this page will be updated on a regular basis to include additional information and cover emerging .NET techniques. This is a community driven project, so you are encouraged to contribute as well, and we are counting on your feedback.

.NET Framework is a software framework developed by Microsoft. It is powerful, flexible, and can be adapted to a broad range of uses. Expert .NET best practices are not hard to find on the web, due to its popularity. However, by featuring the most up-to-date .NET advice, we think we can do better.

Check out the Toptal resource pages for additional information on .NET, such as interview questions.

12 Visual Studio Extensions You Ought to Know

Visual Studio extensions are adding new functionality or fixing unwanted default behavior of the IDE. Many .NET developers are well familiar with some great extensions, such as ReSharper. However, there are many small yet useful extensions that do one job but do it very well.

Installing extensions is very easy: go to Tools > Extensions and Updates..., click Online, then search for a needed extension and click the Download button. That’s it. Note some extensions may require you to restart Visual Studio.

All extensions in this list satisfy the following criteria:

  • They are freeware, even for commercial use.
  • They are serving one function, and are not a multi-purpose tool.
  • They are general purpose extensions, and are not aimed at just web or mobile development.

1. SpellChecker


Just don’t install them all at the same time.

2. StopOnFirstBuildError

This simple plugin just stops the building process immediately if one project fails to build.

3. VSColorOutput

Color output for build and debug windows.

4. Array Visualizer

This is designed to display arrays, jagged and up to 4D while debugging an application. Now it supports various charts, like bar, area, and stack.

5. Regex Tester

Regular expression tester for Visual Studio 2010-2015.

6. NoGit

Disables the Git Source Control Provider when a solution is opened.

7. ShowMyGitBranch

A Visual Studio extension that displays your current Git branch on the title bar.

8. Disable No Source Available Tab

This small extension will prevent the tool window with title “No Source Available” from appearing in Visual Studio, and preserve the focus on the currently active tab.

9. Copy As HTML

Copy selected code in HTML format while preserving syntax highlighting, indentation, background colour and font.

10. BuildVision

This simple extension visualizes your build process.

11. SaveAllTheTime

SaveAllTheTime makes it so you never commit files to Git without saving ever again. It also reminds you to commit often by showing you a widget at the bottom right corner of your screen.

12. TabSanity

Navigate through tabs-as-spaces as if they were actually tabs.


  • Small f22d7eda5923ace61bd8ca42192f6ffaAndrei SmirnovSaint-Petersburg, RussiaView Andrei
Like what you're reading?
Get the latest updates first.
No spam. Just great engineering and design posts.
Like what you're reading?
Get the latest updates first.
Thank you for subscribing!
You can edit your subscription preferences here.

11 NuGet Packages You Ought to Know

Everyday we use a lot of NuGet packages. Most of them are well-known and required to install, while some of them are optional. Nowadays, most of the “optional” packages have become industrial standard, like NUnit or Newtonsoft.Json. However, developers keep developing new software, and we see many new packages appearing on the NuGet Gallery.

In this article, we will review several general-purpose packages that are worth your attention. By “general purpose” I mean that you are very likely to use some of these packages, no matter what are you developing: a web application, server side or a desktop application.

1. HangFire

An easy way to perform fire-and-forget, delayed, and recurring tasks inside ASP.NET applications. No Windows Service required.

Fire-and-forget tasks:

// Static methods are for demo purposes
    () => Console.WriteLine("Simple!"));

Delayed tasks:

    () => Console.WriteLine("Reliable!"), 

Recurring tasks:

    () => Console.WriteLine("Transparent!"), 

2. NodaTime

A better date and time API for .NET.

Jon was born on June 19th, 1976 (Gregorian). How old is he now, in the UK time zone?

LocalDate birthDate = new LocalDate(1976, 6, 19);
DateTimeZone zone = DateTimeZoneProviders.Tzdb["Europe/London"];
ZonedClock clock = SystemClock.Instance.InZone(zone);
LocalDate today = clock.GetCurrentLocalDateTime().Date;
Period age = Period.Between(birthDate, today);
Console.WriteLine("Jon is: {0} years, {1} months, {2} days old.", age.Years, age.Months, age.Days);

3. UniRest

UniRest is a set of lightweight HTTP libraries available in multiple languages.

The library is available for all mainstream languages preserving the same API. .NET version has portable library and can run virtually on all .NET Framework versions.

A basic POST request example:

HttpResponse<MyClass> jsonResponse = Unirest.post("http://httpbin.org/post")
  .header("accept", "application/json")
  .field("parameter", "value")
  .field("foo", "bar")

4. Shouldly

Shouldly is an assertion framework which focuses on giving great error messages when the assertion fails while being simple and terse.

Assert.That(map.IndexOfValue("boo"), Is.EqualTo(2));    // -> Expected 2 but was 1
map.IndexOfValue("boo").ShouldBe(2);                    // -> map.IndexOfValue("boo") should be 2 but was 1

5. MarkdownLog

Lightweight .NET component for programmatically generating Markdown. Useful for producing rich diagnostic logs with minimal dependencies.

var data = new[]
    new{Year = 1991, Album = "Out of Time", Songs=11, Rating = "* * * *"},
    new{Year = 1992, Album = "Automatic for the People", Songs=12, Rating = "* * * * *"},
    new{Year = 1994, Album = "Monster", Songs=12, Rating = "* * *"}


// Produces:
//     Year | Album                    | Songs | Rating   
//     ----:| ------------------------ | -----:| --------- 
//     1991 | Out of Time              |    11 | * * * *  
//     1992 | Automatic for the People |    12 | * * * * *
//     1994 | Monster                  |    12 | * * *    

6. SharpZipLib

ziplib is a Zip, GZip, Tar and BZip2 library written entirely in C# for the .NET platform.

How to create a Zip file:

FastZip fastZip = new FastZip();

bool recurse = true;  // Include all files by recursing through the directory structure
string filter = @"\.txt$"; // Only files ending in ".txt"
fastZip.CreateZip("fileName.zip", @"C:\SourceDirectory", recurse, filter);

7. Humanizer

Humanizer meets all your .NET needs for manipulating and displaying strings, enums, dates, times, timespans, numbers and quantities.

Few examples that do not require explanation:

DateTime.UtcNow.AddHours(-30).Humanize() => "yesterday"
DateTime.UtcNow.AddHours(-2).Humanize() => "2 hours ago"
TimeSpan.FromMilliseconds(1299630020).Humanize(4) => "2 weeks, 1 day, 1 hour, 30 seconds"
"string".Pluralize() => "strings"
"Men".Singularize() => "Man"
"man".ToQuantity(1) => "1 man"

8. QuickGraph

Generic Graph Data Structures and Algorithms for .NET.

The most demanded feature is topological sorting:

DataSet ds = new MyDataSet(); // your dataset
var graph = ds.ToGraph();  // wraps the dataset into a DataSetGraph
foreach(DataTable table in graph.TopologicalSort()) // applies a topological sort to the dataset graph
    Console.WriteLine(table.TableName); // in which order should we delete the tables?

9. EPPlus

EPPlus is a .NET library that reads and writes Excel 2007/2010 files using the Open Office Xml format (XLSX).

This is a sample how you can return a spreadsheet from your web server without access to the file system.

private void DumpExcel(DataTable tbl)
    using (ExcelPackage pck = new ExcelPackage())
        //Create the worksheet
        ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Demo");

        //Load the datatable into the sheet, starting from cell A1. Print the column names on row 1
        ws.Cells["A1"].LoadFromDataTable(tbl, true);

        //Format the header for column 1-3
        using (ExcelRange rng = ws.Cells["A1:C1"])
            rng.Style.Font.Bold = true;

        //Example how to Format Column 1 as numeric 
        using (ExcelRange col = ws.Cells[2, 1, 2 + tbl.Rows.Count, 1])
            col.Style.Numberformat.Format = "#,##0.00";
            col.Style.HorizontalAlignment = ExcelHorizontalAlignment.Right;

        //Write it back to the client
        Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        Response.AddHeader("content-disposition", "attachment;  filename=ExcelDemo.xlsx");

10. HtmlAgilityPack

It is a .NET code library that allows you to parse “out of the web” HTML files. The parser is very tolerant with “real world” malformed HTML.

For example, here is how you would fix all href tags in an HTML file:

HtmlDocument doc = new HtmlDocument();
foreach(HtmlNode link in doc.DocumentElement.SelectNodes("//a[@href"])
	HtmlAttribute att = link["href"];
	att.Value = FixLink(att);

11. FluentValidation

A small validation library for .NET that uses a fluent interface and lambda expressions for building validation rules.


using FluentValidation;

public class CustomerValidator: AbstractValidator<Customer> {
  public CustomerValidator() {
    RuleFor(customer => customer.Surname).NotEmpty();
    RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
    RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
    RuleFor(customer => customer.Address).Length(20, 250);
    RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");

  private bool BeAValidPostcode(string postcode) {
    // custom postcode validating logic goes here

Customer customer = new Customer();
CustomerValidator validator = new CustomerValidator();
ValidationResult results = validator.Validate(customer);

bool validationSucceeded = results.IsValid;
IList<ValidationFailure> failures = results.Errors;


  • Small f22d7eda5923ace61bd8ca42192f6ffaAndrei SmirnovSaint-Petersburg, RussiaView Andrei
Like what you're reading?
Get the latest updates first.
No spam. Just great engineering and design posts.
Like what you're reading?
Get the latest updates first.
Thank you for subscribing!
You can edit your subscription preferences here.

How to Manage TODO Comments in Visual Studio?

When coding, developers sometimes leave comment shortcuts in the code that need more attention later when the code has to be reviewed or when they have a question for other team members.

The usual practice is to leave a classic comment shortcut, like TODO, as in the following example:

public ActionResult Index()
    ViewData["Message"] = ""; // TODO: compose the message text;
    return View();

Here is the example with the unit test:

public void ValidationLogicTest()
    // TODO: implement the unit test
    Assert.Fail("Not implemented yet");

Many .NET developers use ReSharper to highlight TODO comments and notes with blue color, so it is easy to find them. However, in Visual Studio we can use Task List. Task List tracks code comments that use shortcuts, or tokens, such as TODO or NOTE, or any other custom named tokens, and adds shortcuts that will take the user directly to a predefined location in the code. When a user clicks on the item in the Task List, it will take him to its location in the source code. By default, Visual Studio includes the following tokens: HACK, TODO, UNDONE, and NOTE, where the case is insensitive. As mentioned, users can add custom tokens by going to Tools > Options > Environment folder > Task List. Later, to open Task List window, users can go to the menu View > Task List, or simply use shortcut Ctrl + \ , T.

While we are talking about TODO comments, here is an additional tip: write comment on the same line with the word TODO, like in the following example:

// TODO: Need to verify if the user is logged.

The reason is that when you will search in all files from the solution for TODO word, you will see in search results the line with this word. And if to keep TODO and comment on the same line, you will see and read the comment text right in search results.

// TODO: comment text goes here 
// TODO: cleanup the code
// TODO: switch to configuration settings
// TODO: bla-bla

Otherwise you will see something like that:



  • Small dmitry.pavlov.remote.asp.net.developerDmitry PavlovSaint Petersburg, RussiaView Dmitry
Like what you're reading?
Get the latest updates first.
No spam. Just great engineering and design posts.
Like what you're reading?
Get the latest updates first.
Thank you for subscribing!
You can edit your subscription preferences here.

How to Speed Up the Writing of Code

In Visual Studio, there is a feature named “code snippets”, which allows simplifying writing common code structures.

For example, if you have to create a for statement, you will probably type this block of code:

for (int i = 0; i < 10; i++)

Now imagine, if you type for and press TAB on the keyboard, and you get a code generated by Visual Studio. As you keep pressing TAB to move forward, you can adjust the variable names. If you want to get back in the code snippet, simply use SHIFT+TAB.

There are some special words named shortcuts for the snippets, and you can see available snippets in Visual Studio menu Tools > Code Snippets Manager, where snippets are displayed by language. You can also add your snippets quickly using a VS extension. Or, if you want to do it manually.

This feature also works with more statements such as loop, while, and try/catch/finally.


  • Small dmitry.pavlov.remote.asp.net.developerDmitry PavlovSaint Petersburg, RussiaView Dmitry

Submit a tip

Fields marked with an asterisk (*) are required
Thanks for submitting your tip proposal
Our editorial staff will review it shortly. Please note that tips proposals are subject to review and editing, and may or may not be selected for posting, at the sole discretion of Toptal, LLC.