Prevent Secrets From Accidentally Being Committed to Source Control in ASP.NET Core Apps

One problem when dealing with developer “secrets” in development is accidentally checking them into source control. These secrets could be connection strings to dev resources, user IDs, product keys, etc.

To help prevent this from accidentally happening, the secrets can be stored outside of the project tree/source control repository. This means that when the code is checked in, there will be no secrets in the repository.

Each developer will have their secrets stored outside of the project code. When the app is run, these secrets can be retrieved at runtime from outside the project structure.

One way to accomplish this in ASP.NET Core  projects is to make use of the Microsoft.Extensions.SecretManager.Tools NuGet package to allow use of the command line tool. (also if you are targeting .NET Core 1.x , install the Microsoft.Extensions.Configuration.UserSecrets NuGet package).

Setting Up User Secrets

After creating a new ASP.NET Core project, add a tools reference to the NuGet package to the project, this will add the following item in the project file:

<DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.0" />

Build the project and then right click the project and you will see a new item called “Manage User Secrets” as the following screenshot shows:

Managing user secrets in Visual Studio

Clicking menu item will open a secrets.json file and also add an element named UserSecretsId to the project file. The content of this element is a GUID, the GUID is arbitrary but should be unique for each and every project.

<UserSecretsId>c83d8f04-8dba-4be4-8635-b5364f54e444</UserSecretsId>

User secrets will be stored in the secrets.json file which will be in %APPDATA%\Microsoft\UserSecrets\<user_secrets_id>\secrets.json on Windows or ~/.microsoft/usersecrets/<user_secrets_id>/secrets.json on Linux and macOS. Notice these paths contain the user_secrets_id that matches the GUID in the project file. In this way each project has a separate set of user secrets.

The secrets.json file contains key value pairs.

Managing User Secrets

User secrets can be added by editing the json file or by using the command line (from the project directory).

To list user secrets type: dotnet user-secrets list At the moment his will return “No secrets configured for this application.”

To set (add) a secret: dotnet user-secrets set "Id" "42"

The secrets.json file now contains the following:

{
  "Id": "42"
}

Other dotnet user-secrets  commands include:

  • clear - Deletes all the application secrets
  • list - Lists all the application secrets
  • remove - Removes the specified user secret
  • set - Sets the user secret to the specified value

Accessing User Secrets in Code

To retrieve users secrets, in the startup class, access the item by key, for example:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    var secretId = Configuration["Id"]; // returns 42
}

One thing to bear in mind is that secrets are not encrypted in the secrets.json file, as the documentation states: “The Secret Manager tool doesn't encrypt the stored secrets and shouldn't be treated as a trusted store. It's for development purposes only. The keys and values are stored in a JSON configuration file in the user profile directory.” & “You can store and protect Azure test and production secrets with the Azure Key Vault configuration provider.”

There’s a lot more information in the documentation and if you plan to use this tool you should read through it.

Using the C# 6.0 nameof Operator in ASP.NET MVC Razor Views

Traditionally to reference an action and/or a controller in a Razor view the action/controller name is represented as a string as shown in the following code:

<ul class="nav navbar-nav">
    <li>@Html.ActionLink("Home", "Index", "Home")</li>
    <li>@Html.ActionLink("About", "About", "Home")</li>
    <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

This means that some brittleness can be introduced into the application, for example if the name of the controller or action is changed these strings can become outdated and cause a runtime error.

The nameof operator introduced in C# 6.0 gets the (non fully qualified) name of the type passed to it. So for example nameof(HomeController) will return the string “HomeController”. The nameof operator can also be used with type members, for example nameof(HomeController.Index) will return the string “Index”.

The following code shows the use of nameof to get the action name programmatically without needing a magic string:

<ul class="nav navbar-nav">
    <li>@Html.ActionLink("Home", nameof(HomeController.Index), "Home")</li>
    <li>@Html.ActionLink("About", nameof(HomeController.About), "Home")</li>
    <li>@Html.ActionLink("Contact", nameof(HomeController.Contact), "Home")</li>
</ul>

Now if the name of the HomeController.Index method is renamed, for example to HomeController.Index2, there will be a build time error: “'HomeController' does not contain a definition for 'Index'”.

The use of nameof can also be applied to the controller name:

<ul class="nav navbar-nav">
    <li>@Html.ActionLink("Home", nameof(HomeController.Index), nameof(HomeController) )</li>
    <li>@Html.ActionLink("About", nameof(HomeController.About), nameof(HomeController))</li>
    <li>@Html.ActionLink("Contact", nameof(HomeController.Contact), nameof(HomeController))</li>
</ul>

The preceding code however causes errors, the link URL produced is “http://localhost:26663/HomeController/About” rather than the correct “http://localhost:26663/Home/About” (note the extra Controller text).

One way to rectify this would be to remove the word “Controller” from the string produced by nameof:

<ul class="nav navbar-nav">
    <li>@Html.ActionLink("Home", nameof(HomeController.Index), nameof(HomeController).Replace("Controller", ""))</li>
    <li>@Html.ActionLink("About", nameof(HomeController.About), nameof(HomeController).Replace("Controller", ""))</li>
    <li>@Html.ActionLink("Contact", nameof(HomeController.Contact), nameof(HomeController).Replace("Controller", ""))</li>
</ul>

This technique introduces some code duplication, which could be addressed by creating a string extension method:

public static class ControllerExtensions
{
    public static string RemoveController(this string fullControllerClassName)
    {
        return fullControllerClassName.Replace("Controller", "");
    }
}

And then using this extension method:

<ul class="nav navbar-nav">
    <li>@Html.ActionLink("Home", nameof(HomeController.Index), nameof(HomeController).RemoveController())</li>
    <li>@Html.ActionLink("About", nameof(HomeController.About), nameof(HomeController).RemoveController())</li>
    <li>@Html.ActionLink("Contact", nameof(HomeController.Contact), nameof(HomeController).RemoveController()))</li>
</ul>

Alternatively a static method could be created:

public static class ControllerExtensions
{
    public static string ShortControllerName<T>() where T : Controller
    {
        return typeof(T).Name.Replace("Controller", "");
    }
}

And then called from the view:

<ul class="nav navbar-nav">
    <li>@Html.ActionLink("Home", nameof(HomeController.Index), ControllerExtensions.ShortControllerName<HomeController>())</li>
    <li>@Html.ActionLink("About", nameof(HomeController.About), ControllerExtensions.ShortControllerName<HomeController>())</li>
    <li>@Html.ActionLink("Contact", nameof(HomeController.Contact), ControllerExtensions.ShortControllerName<HomeController>())</li>
</ul>

This technique may not work in all situations, for example if an action method is using the [ActionName] attribute:

[ActionName("Contact2")]
public ActionResult Contact()
{    
    // ...
}
In the preceding example, nameof(HomeController.Contact) will return the string “Contact” and the URL “http://localhost:26663/Home/Contact” wheras the correct URL should be “http://localhost:26663/Home/Contact2” because of the [ActionName("Contact2")] attribute.

Note that to get access to nameof, the view needs to be compiled with C# 6.0 language features enabled.

Using AutoFixture To Generate Anonymous Test Data in Web UI Automation With BDDfy and Seleno

I’m currently working on an AutoFixture Pluralsight course and it got me thinking about using it to generate anonymous test data when writing automated UI tests.

The basic premise is that in addition to using AutoFixture to generate unit test data, it can also be used to populate UI elements where the specific data values are unimportant.

If you are unfamiliar with BDDfy and Seleno, they are part of the TestStack project.

BDDfy allows tests to be written and to produce business readable documentation. Seleno allows the automation of web browsers using Selenium and strongly-typed page object models.

Example Scenario

Imagine that we have an (ASP.NET MVC) web site that allows the addition of members of the royal family.

image

If we wanted to test different king/queen names (but didn’t care about the Regnal number) we could start off by defining some strongly typed (Seleno) page object models:

public class HomePage : Page<AddRoyaltyModel>
{
    public CreatedPage CreateRoyalty(AddRoyaltyModel royal)
    {
        Input.Model(royal);

        return Navigate.To<CreatedPage>(By.Id("Create"));
    }
}

public class CreatedPage : Page
{
}

 

(all the examples in this post are fairly quick-and-dirty to demonstrate the AutoFixture involvement)

 

Next we can write some example in BDDfy (using xUnit.net as the test framework):

public class AddRoyaltyTests
{
    private HomePage _home;
    private CreatedPage _confirmationPage;
    public string Name { get; set; }
    public string Number { get; set; }

    [Fact]
    public void ShouldAddRoyaltiesWithDifferentNames()
    {
        this.Given(x => GivenIAmStartingANewRoyalAddition())
            .And("And I have entered <name> as the royalty name")
            .And("And I have entered <number> as the regnal number")
            .When(x => WhenIChooseToAddTheNewRoyal())
            .Then(x => ThenIShouldSeeAConfirmationOfTheNewRoyalHavingBeenAdded())
            .WithExamples(new ExampleTable("name", "number")
                          {
                              {"Richard", "I"},
                              {"Henry", "I"},
                              {"Elizabeth", "I"}
                          })
            .BDDfy();            
    }



    private void GivenIAmStartingANewRoyalAddition()
    {
        _home = Host.Instance.NavigateToInitialPage<HomeController, HomePage>(x => x.Index());
    }        

    private void WhenIChooseToAddTheNewRoyal()
    {
        var royal = new AddRoyaltyModel
        {
            Name = this.Name,
            RegnalRomanNumeral = this.Number
        };

        _confirmationPage = _home.CreateRoyalty(royal);
    }

    private void ThenIShouldSeeAConfirmationOfTheNewRoyalHavingBeenAdded()
    {
        Assert.Equal("Created ok", _confirmationPage.Title);
    }
}

Notice in the preceding code that even though we don’t care about the Regnal number we are still supplying it in the examples. We could just set it manually to a hardcoded value, and in this simple example that might be ok, but if we had a form with many fields then this  will introduce extra work and may make the test less “refactor-safe”.

The following code shows the removal of the Regnal name/number:

public class AddRoyaltyTestsUsingAutoFixture
{
    private HomePage _home;
    private CreatedPage _confirmationPage;
    public string Name { get; set; }

    [Fact]
    public void ShouldAddRoyaltiesWithDifferentNames()
    {
        this.Given(x => GivenIAmStartingANewRoyalAddition())
            .And("And I have entered <name> as the royalty name")
            .When(x => WhenIChooseToAddTheNewRoyal())
            .Then(x => ThenIShouldSeeAConfirmationOfTheNewRoyalHavingBeenAdded())
            .WithExamples(new ExampleTable("name")
                          {
                              "Richard",
                              "Henry",
                              "Elizabeth"
                          })
            .BDDfy();            
    }

    private void GivenIAmStartingANewRoyalAddition()
    {
        _home = Host.Instance.NavigateToInitialPage<HomeController, HomePage>(x => x.Index());
    }        

    private void WhenIChooseToAddTheNewRoyal()
    {
        var fixture = new Fixture();

        // Use AutoFixture to create anonymous data for all properties except
        // name which is set to the BDDfy example value
        var royal = fixture.Build<AddRoyaltyModel>()
            .With(x => x.Name, this.Name)
            .Create();

        _confirmationPage = _home.CreateRoyalty(royal);
    }

    private void ThenIShouldSeeAConfirmationOfTheNewRoyalHavingBeenAdded()
    {
        Assert.Equal("Created ok", _confirmationPage.Title);
    }
}

In this version, AutoFixture’s Build method is being used to automatically generate test data for all the fields, except the royal name which is set to the name(s) specified in the BDDfy examples.

Running this test results in the following automation:

SelenoAutofixture

 

And produces the following HTML BDDfy report:

image

New Pluralsight Course - Automated ASP.NET MVC Testing: End to End

My new Pluralsight course Automated ASP.NET MVC Testing: End to End was just published.

The course looks at tools and techniques to be able to tests models, controller actions, Razor view rendering logic, and implement automated functional UI browser testing.

The course wraps up by showing how to design and implement a continuous integration build in TeamCity that runs the tests created during the course.

Check it out the full table of contents.

Consuming Server-Side SignalR Events in Universal Windows App Clients

In a previous article I wrote about creating server side SignalR timer events.

As part of my learning of SignalR I wanted to see how easy it would be to create a Universal Windows app consuming these server side events.

So first off I created a new blank Universal app:

creating universal app in Visual Studio screenshot

 

Next installed the SignalR NuGet package into both app projects: install-package Microsoft.AspNet.SignalR.Client

In the Windows 8.1 Store app project XAML I added a simple bound TextBlock that will display the server messages:

<Page
    x:Class="UpTimeUni.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:UpTimeUni"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Viewbox>
            <TextBlock Text="{Binding Uptime}">please wait...</TextBlock>
        </Viewbox>
    </Grid>
</Page>

I also added similar XAML in the Windows Phone 8.1 main page.

More...

Using Server Side Timers and SignalR in ASP.NET MVC Applications

I thought it would be fun to create an “Internet uptime” page that you can see live here on Azure Websites. It shows how long the Internet (since ARPANET) has been around for.

image

Creating a Class that can be Managed by ASP.NET

The HostingEnvironment.RegisterObject method can be used to register an instance of an object that has its lifetime managed by the hosting environment.

To register an object it must implement the IRegisteredObject interface.

This interface defines a Stop method which gets called when ASP.NET needs to shutdown the app domain.

So, in the application start we can create an instance of our class and register it:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    RouteConfig.RegisterRoutes(RouteTable.Routes);

    HostingEnvironment.RegisterObject(new BackgroundUptimeServerTimer());
}

Creating a SignalR Hub to Send Messages from the Server to Client

Next we create a SignalR hub and the HTML.

So the hub class is called UptimeHub:

public class UptimeHub : Hub
{
}

We can get the server to call a client JavaScript method called “internetUpTime” in the HTML page and have this client code display the what’s been sent from the server timer.

The following shows the complete HTML for the page. Notice the “hub.client.internetUpTime = function (time) …” this function will get executed every time our server timer event fires.

More...

In Process Http Server for Integration Test Faking with Owin, Katana, and WebAPI

Sometimes when integration testing we need an HTTP endpoint. We can set one up in our solution (for example a Web Api project) and make sure it’s running before we execute our integration tests but it can be painful. Also consider when running on a build server, the web site will need to be provisioned, etc.

For isolated integration tests that require some HTTP endpoint we can create an HTTP endpoint from within our test code that doesn’t require a separate web project. This means that when tests run they have no external dependency in the sense of a “real” website being hosted somewhere – even if that somewhere is on the local dev machine. Another advantage of the approach outlined below is that because it’s all in-process it’s also faster than actually going through the network stack.

The System Under Test

We are going to test the following class that calls a service to change a string to uppercase:

using System;
using System.Net;

namespace ClassLibrary
{
    public class ToUpperServiceGateway
    {
        private readonly string _serviceEndpoint;

        public ToUpperServiceGateway(string serviceEndpoint)
        {
            _serviceEndpoint = serviceEndpoint;
        }

        public string MakeUppercase(string lowercase)
        {
            using (var wc = new WebClient())
            {
                return wc.DownloadString(_serviceEndpoint + "/" + lowercase);
            }
        }
    }
}

This code uses WebClient to call a web service. In the integration tests we want to spin up a website that will return a mock value for example.

Writing the Initial Test Code

So an initial test could look somethine like:

using Xunit;

namespace ClassLibrary.IntegrationTests
{
    public class UpperCaseTests
    {
        [Fact]
        public void ShouldGetUppercase()
        {
            var sut = new ToUpperServiceGateway("http://localhost:8084/api/toupper");

            var upper = sut.MakeUppercase("hello");

            Assert.Equal("HELLO", upper);            
        }
    }
}

If we run this we get “System.Net.WebException Unable to connect to the remote server” as we’d expect as there’s no website at the address.

Creating an In-Process Web API Endpoint

First off, in the test project install a few of NuGets: Microsoft.AspNet.WebApi.OwinSelfHost and Microsoft.Owin.Testing.

The first thing is to create a Web API controller, again in the test project, to fake out a real service:

using System.Web.Http;

namespace ClassLibrary.IntegrationTests
{
    public class ToUpperController : ApiController
    {
        public string Get(string lower)
        {            
            return "FAKE"; // fake value
        }
    }
}

Here, regardless of what’s passed in we’re just returning a fake value.

The next task is to create some configuration for Owin setting up our test controller:

using System.Web.Http;
using Owin;

namespace ClassLibrary.IntegrationTests
{
    public class Startup
    {
        public void Configuration(IAppBuilder appBuilder)
        {
            var config = new HttpConfiguration();

            config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{lower}");

            appBuilder.UseWebApi(config);
        }
    }
}

We can now refactor the test to create an in-memory Web API controller that can respond to our SUT:

using Microsoft.Owin.Hosting;
using Xunit;

namespace ClassLibrary.IntegrationTests
{
    public class UpperCaseTests
    {
        [Fact]
        public void ShouldGetUppercase()
        {
            using (WebApp.Start<Startup>("http://localhost:8084")) // base hosting address
            {
                var sut = new ToUpperServiceGateway("http://localhost:8084/api/toupper"); 
                // api/toupper matches our test controller / route

                var result = sut.MakeUppercase("hello");

                Assert.Equal("\"FAKE\"", result); // extra " because Web API response is not returning text/plain
            }
        }
    }
}

The test now passes, as our SUT connects to our in-memory test controller.

Note: For even simpler code that doesn’t require a test controller we could also use Nancy.

Testing ASP.Net MVC Controllers with FluentMVCTesting

FluentMVCTesting facilitates the writing of tests against MVC controllers in a fluent way.

FluentMVCTesting is available via NuGet: Install-Package TestStack.FluentMVCTesting

There’s a number of things that FluentMVCTesting can help to test such as:

  • A controller action returns the correct view
  • A controller action returns the correct HTTP status
  • A controller action returns an empty result
  • A controller action returns a view if there are model errors
  • A controller action returns a view with the correct model data
  • A controller action should redirect to a Url / Route / Action

It’s also not tied to a specific testing framework, so it can be used with NUnit, xUnit.net, MSTest, etc.

Examples

var sut = new ExampleController();

sut.WithCallTo(x => x.Show()).ShouldRenderView("Orders");

The preceding test code is testing the ExampleController. It is testing that when the Show() action is called then the Orders view is rendered.

The following code checks that an expected HTTP status is returned.

var sut = new ExampleController();

sut.WithCallTo(x => x.MakeAnError())
    .ShouldGiveHttpStatus(HttpStatusCode.InternalServerError);

 

To see more of what FluentMVCTesting can do check out my Building the Right Thing in .NET with TestStack Pluralsight course, check out the documentation, or check it out on GitHub.

Introducing JS Name-O-Tron – Find a Name for Your JavaScript Library

As a Microsoft MVP I get free Azure credits to use every month, so I thought I’d better start making use of them :)

screenshot of JS Name-O-Tron application on Azure

JS Name-O-Tron is the first web site I’ve deployed to Azure and I’m pleased to say it was crazy-easy :)

It generates a random word and adds “.js” to it – you can then check if there’s an existing library with that name (GitHub, CodePlex, and NuGet).

I used Visual Studio 2013 to create a new ASP.Net application and chose MVC (v5) which resulted in a Bootstrapped site with a default Home controller and views.

More...

Getting Started with SASS for Microsoft Developers

Sass (Syntactically Awesome Style Sheets) tries to make CSS fun again.

It's a set of "extensions" on top of standard CSS that make it easier to write and maintain style sheets.

A Sass file compiles down to regular CSS so it doesn't require any special browser plug-ins.

This article is aimed at Microsoft developers but the Sass language sections apply to anyone wanting to get an overview of Sass, regardless of the web programming platform or IDE you're using.

More...