Unit Testing the HttpContext in Controllers

Introduction

When it comes to unit testing, it is common to use mocking to replace “external” services, that is, those that are not part of the subject under test. Not everything can be mocked, and, sometimes, when we instantiate non-POCO classes, such as controllers (ControllerBase), there are lots of things that are not instantiated by the framework and are left for us do to. Just think, for example, if you want to access request or quest string data or know if the user is logged in?

In this post I will talk about two things: the user identity and the request data.

The HttpContext

Inside of a controller action method, it is common to get information which actually comes from the the context (the HttpContext property):

All of these properties get routed to the HttpContext property, which is read-only. It turns out that this property is itself routed to the ControllerContext’s property’s own HttpContext, but the ControllerContext can be set:

var controller = new HomeController();
controller.ControllerContext = new ControllerContext();

So, if we want to set a controller’s HttpContext property, all we have to do is set the ControllerContext’s HttpContext:

controller.ControllerContext.HttpContext = new DefaultHttpContext();

The DefaultHttpContext class is the default implementation of the abstract HttpContext class that is included in ASP.NET Core.

Features

All of the .NET and ASP.NET Core is very modular and designed for extensibility, so it should come as no surprise that all of the HttpContext features are provided as features and it’s easy to provide implementations for them.

Features are accessible through the Features collection and can be set using as key one interface, which is generally a core interface that identifies that feature:

context.Request.Set<IFormFeature>(new FormCollection(request));

The DefaultHttpContext takes in one of its constructors a collection of features, from which it can extract its functionality.

Request Data

When we talk about the request we can be talking about:

  • Form data (including files)
  • The query string

Each is implemented by its own feature. So, if we want to mock form data, we would do something like this, leveraging the IFormFeature:

var request = new Dictionary { { “email”, “rjperes@hotmail.com” }, { “name”, “Ricardo Peres” } }; var formCollection = new FormCollection(request); var form = new FormFeature(formCollection);

var features = new FeatureCollection(); features.Set<IFormFeature>(form); var context = new DefaultHttpContext(features);

This allows us to write code like this, from inside the :

var email = HttpContext.Request["email"];

As for the query string, we would do it like this, using IQueryFeature:

var request = new Dictionary { { “id”, “12345” } }; var queryCollection = new QueryCollection(request); var query = new QueryFeature(queryCollection);

var features = new FeatureCollection(); features.Set<IQueryFeature>(form); var context = new DefaultHttpContext(features);

This code gives us the ability to do this:

var id = HttpContext.Request.Query["id"];

Response

What about sending responses, HTTP status codes and cookies? I’ve got you covered too! The feature contract for the response is IHttpResponseFeature and we add it like this:

var response = new HttpResponseFeature();

var features = new FeatureCollection(); features.Set<IHttpResponseFeature>(response); var context = new DefaultHttpContext(features);

var responseCookies = new ResponseCookiesFeature(context.Features);

Notice that the ResponseCookiesFeature is a little awkward, as it takes the feature collection in its constructor.

With this on, you can set the response status or some cookies on the response of your action:

Response.StatusCode = 400;
Response.Cookies.Append("foo", "bar");

User Identity

As for the user identity, it’s much simpler, we just need to create a ClaimsPrincipal with any claims that we want:

var context = new DefaultHttpContext(features)

{ User = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]

{

     new Claim(ClaimTypes.Name, “<username>”),

new Claim(ClaimTypes.Role, “<role>”)

    })) };

You can just pass any username and roles you want, and they will be made available to the controller’s User property.

Conclusion

As you can see, with a little bit of work, almost anything is possible in .NET Core, and, particularly, when it comes to unit tests! Stay tuned for more! Winking smile

Dynamic Routing in ASP.NET Core 3

ASP.NET Core 3 introduced a not so talked about feature which is dynamic routing. In a nutshell, it means that it is possible to decide at runtime the controller, action and route tokens that a request will be dispatched to. The idea is to map a route pattern to a dynamic route handler, like this:

app.UseEndpoints(endpoints =>
{
    endpoints.MapDynamicControllerRoute<SearchValueTransformer>("search/{**product}");
});

This maps a route of “/search/<anything>” to a class SearchValueTransformer, which is then responsible for supplying values for the controller and action.

This SeachValueTransformer class must inherit from DynamicRouteValueTransformer, this is the abstract base class for all dynamic route handling, and it only has one method to implement, TransformAsync. The example I am providing here is that of a service that receives some random query for a product on the URL and then decides to which controller it will be forwarded to. A sample implementation of this class would be:

class SearchValueTransformer : DynamicRouteValueTransformer { private readonly IProductLocator _productLocator; public SearchValueTransformer(IProductLocator productLocator) { this._productLocator = productLocator; } public override async ValueTask TransformAsync(

HttpContext httpContext, RouteValueDictionary values) { var productString = values[“product”] as string; var id = await this._productLocator.FindProduct(“product”, out var controller); values[“controller”] = controller; values[“action”] = “Get”; values[“id”] = id; return values; } }

As you can see, it takes an instance of an IProductLocator (I will get to that in a moment) in its constructor, which means that it supports dependency injection. The TransformAsync extracts a “product” parameter from the route – I am skipping validation because if we got here that’s because we matched the route – which it then uses to call the stored IProductLocator instance to retrieve the id and controller, which are then set as route parameters. The result route is then returned.

The SearchValueTransformer needs to be registered in the dependency injector too:

services.AddSingleton<SearchValueTransformer>();

The actual lifetime is irrelevant, here I am setting it as singleton because the SearchValueTransformer holds a single IProductLocator which is itself a singleton and nothing else.

As to the IProductLocator, here is it’s interface:

public interface IProductLocator
{
    Task<string> FindProduct(string product, out string controller);
}

The actual implementation, I leave it up to you, it must apply some logic to the product passed in the URL to decide which controller should be used for search it, and then return some reference and a controller responsible for returning information about it. This interface and its implementation must also be registered:

services.AddSingleton<IProductLocator, ProductLocator>();

And this is it. This may serve as a complement to static routing, other uses include translating route parts (controller, action) on the fly. As always, hope you find this useful!

Accessing the HttpContext from a DbContext

Sometimes it might be necessary to access the current HttpContext from inside a DbContext, namely, from inside the OnConfiguring or OnModelCreating methods. Why? Well, for once, because of multitenancy: we may want to be able to decide the connection string to use based on the requesting or the host’s domain, the current user or some other request parameter. Here the internal dependency injection (Instance) can’t help, because it cannot be used inside these methods.

The only option we have is to inject the IHttpContextAccessor class through our DbContext class’ constructor, and, from it, get hold of the HttpContext.

First we need to register the IHttpContextAccessor service in ConfigureServices:

services.AddHttpContextAccessor();

We also need to register our context for dependency injection:

services.AddDbContext<MyContext>();

A context registered this way needs to have a special constructor that has a parameter of type DbContextOptions (or DbContextOptions<MyContext>), in our case, we just need to add an extra parameter of type IHttpContextAccessor:

public class MyContext : DbContext
{
    public MyContext(DbContextOptions options, IHttpContextAccessor httpContextAccessor) : base(options)
    {
        this.HttpContextAccessor = httpContextAccessor;
    }

    protected IHttpContextAccessor HttpContextAccessor { get; }
}

Finally, when you need to access the HttpContext, you just need to retrieve it from the IHttpContextAccessor:

protected internal override void OnConfiguring(DbContextOptionsBuilder builder)
{
    var httpContext = this.HttpContextAccessor.HttpContext;
    var tenantService = httpContext.RequestServices.GetService<ITenantService>();
    var connectionString = tenantService.GetConnectionString(httpContext);

    builder.UseSqlServer(connectionString);

    base.OnConfiguring(builder);
}

Here the hypothetical ITenantService provides a method GetConnectionString that returns a connection string for the current HttpContext, and we use it with the SQL Server provider.

Hope you find this useful! Winking smile

C# 8.0 and .NET Core 3.0 – Modern Cross-Platform Development – Fourth Edition Review

C# 8.0 and .NET Core 3.0 – Modern Cross-Platform Development

This is a book written by Mark J. Price for Packt Publishing. I must say that I don’t know Mark, but I was asked by Pack to review this book, which I gladly did!

The topics covered in this book are vast, so it should be no surprise the size of it: more than 800 pages. It spawns across 21 chapters, each of them ends with some exercises. It talks about pretty much everything .NET, as you can see:

Chapter 1

Introduction to Visual Studio Code and Visual Studio 2019 for Windows and Mac. Presents some useful extensions for Visual Studio Code. Talks a bit about the .NET Framework and its branches and offspring, Xamarin, Mono and .NET Core. Also explains the intermediate language that .NET compiles to and how to produce native code from .NET. Also shows how to use Visual Studio Code to get code from GitHub and build console apps. Finally, it gives some pointers on how to get support from the Internet.

Chapter 2

Presents all the C# versions from 1 until 8, the last one to date. Shows how to enable a specific version on a .NET project. Gives a an overview of the unchanging C# language features, like variables, data types, reference and value types, and presents a simple example on how to get input from the user.

Chapter 3

Expands on the C# language started on the previous chapter introducing branching, conditions, pattern matching, assignment, operators, loops and casts.

Chapter 4

Introduces functions, how to debug and unit test them.

Chapter 5

Explains Object-Oriented Programming with C#. How references to assemblies and namespaces work. Field and property modifiers. How to use the return values of functions, including tuples. Method overloading, optional parameters. Partial classes. Properties with indexers and different levels of access.

Chapter 6

Talks about interfaces and type inheritance. Explains events and delegates. Generic types. Reference and value types. The dispose pattern. Member overriding and hiding. Preventing inheritance. Polymorphism. Casting. Extension methods.

Chapter 7

Packaging .NET components in assemblies and NuGet packages. The .NET Standard and .NET Core. Publishing applications. Decompiling assemblies. Publishing to NuGet. Porting to .NET Core.

Chapter 8

Common .NET types and operations: numbers, string, regular expressions, collections, spans, indexes, ranges, network resources, types, attributes. Internationalization.

Chapter 9

Files, file streams and serialization. Working with the filesystem. Text encoding. XML and JSON serialisation and compression.

Chapter 10

Data encryption and decryption. Data hashing and signing. Random number generation. User authentication and authorisation.

Chapter 11

Database programming with Entity Framework Core.

Chapter 12

Using LINQ. Custom LINQ methods. LINQ to XML. Parallel LINQ.

Chapter 13

Performance monitoring. Tasks. Synchronizing access to shared resources. async and await.

Chapter 14

ASP.NET Core web applications. SignalR. Blazor.

Chapter 15

ASP.NET Core Razor Pages. Using EF Core with ASP.NET Core. Razor Class Libraries.

Chapter 16

ASP.NET Core MVC.

Chapter 17

Using Content Management Systems (Piranha CMS).

Chapter 18

ASP.NET Core Web API. Swagger and Open API. Health checks. WCF and gRPC are mentioned briefly.

Chapter 19

Machine learning with ML.NET.

Chapter 20

Windows Forms apps. Windows Presentation Foundation apps with .NET Core and Windows Compatibility Pack. The XAML Standard. Modern Windows apps.

Chapter 21

Using Xamarin for building cross-platform mobile apps. Calling web services.

Conclusion

As you can see, this is a lot, and goes from the plain C# language to machine learning and Blazor. I’d say that some topics, such as Content Management Systems, could have been dropped, but other than that, pretty much everything that a developer longing to learn .NET could wish for is here. A great deal of ASP.NET Core, which is good, as it is for sure the strong part of .NET Core. So, if you’re one such developer, this is one book that you may want to get, you won’t feel disappointed! Definitely a good value for money!

Now Reading: C# 8.0 and .NET Core 3.0 – Modern Cross-Platform Development – Fourth Edition

Update: see the review here.

I am now reading C# 8.0 and .NET Core 3.0 – Modern Cross-Platform Development – Fourth Edition, by Mark J. Price, from Packt Publishing. Expect a review from it very soon.

C# 8.0 and .NET Core 3.0 - Modern Cross-Platform Development - Fourth Edition

@MarkJPrice @RavitJain @PacktPub

TypeScript for C# and .NET Core Developers Review

I finished reading Hands-On TypeScript for C# and .NET Core Developers by Francesco Abbruzzese (@f_abbruzzese) for Packt Publishing. As the name states, it is about TypeScript (and JavaScript) and also very much about Angular.

The book is structured like this:

  1. First chapter explains what is TypeScript (version 2.8.3), how to install it using NPM or the SDK, how to create your first project, basic configuration options, the type system and syntax; at all times, it relates the TypeScript syntax with the recent ECMAScript versions, of which TypeScript is a superset
  2. The second one talks about type declaration, including interfaces, classes, unions, tuples, arrays and so on. It also covers operations over types, such as destructuring and spreads. Finally, it presents functions in TypeScript, how to mimic overloading and have optional arguments
  3. Chapter 3 covers DOM manipulation. This is probably something that seasoned web/JavaScript developers are quite familiar with, but, most importantly, it also introduces declaration files
  4. In chapter 4 we learn how to make effective use of classes and interfaces, declare visibility levels and modifiers, and how type compatibility works
  5. Generics is the topic of chapter 5, how to declare generic types and functions and how to enforce constraints
  6. This chapter talks about modules and namespaces, the different ways by which we can resolve and load modules, and also about TypeScript type declarations, which are used to call untyped JavaScript code
  7. Here we learn how to integrate the WebPack bundler and minifier with ASP.NET Core and how we can enable debugging of the source code in Visual Studio
  8. A very important chapter, here we get an overview on how to write reusable libraries and make them available on NPM. Testing goes together with reusability, so we learn how to use Jasmine to unit test our code
  9. In this chapter we learn about symbols, the TypeScript equivalent to decorators in Aspect-Oriented Programming, generator functions and iterators and also promises, used for asynchronous invocations. Not exactly related, but it also covers the fetch API, used for modern AJAX-style interactions
  10. Chapter 10 presents the ASP.NET Core project template for Angular using TypeScript, describes the Angular architecture and key concepts
  11. This chapter teaches us how to interact with form fields, including validations, how the Angular lifecycle works and how to achieve two-way communication, data binding and piping between components
  12. This one presents some advanced Angular features, such as custom attribute and structural directives, which are then used to create animations by doing DOM manipulation
  13. Lastly, this chapter explains what is dependency injection and its benefits and how we can leverage it with TypeScript and Angular. It also describes how we can localize messages and use HTTP-related modules for interaction with external services. Most importantly, it presents the basis of Angular routing and navigation, a must-have for any complex application, and ends with an overview of testing for

At the end of each chapter there is a summary which highlights the key aspects that were introduced in it, poses 10 questions, which are answered in the Assessments chapter.

The book covers TypeScript 2.8.3, which is relatively old by now, but given the pace that TypeScript versions come out, it can hardly surprise us. Some new stuff in TS is missing, of course, but I guess this will always happen. It is essentially a book about TypeScript and Angular, but of course also covers Node.js and, obviously, JavaScript itself. .NET Core here is discussed as leverage to deploy and compile client-side code. The book is quite comprehensive and was actually an interesting read and I definitely learnt a lot.

The source code can be found in GitHub here: https://github.com/PacktPublishing/Hands-On-TypeScript-for-CSharp-and-.NET-Core-Developers.

If you got interested, please go get if from the Packt Publishing site: https://www.packtpub.com/application-development/hands-typescript-c-and-net-core-developers.

Now Reading: Hands-On TypeScript for C# and .NET Core Developers

I started reading a book by my MVP colleague Francesco Abbruzzese (@f_abbruzzese) on C# and TypeScript: Hands-On TypeScript for C# and .NET Core Developers. So far, it seems an interesting reading! Will write a review about it here, once I finish reading it. In case you want to know more, go get if from the Packt Publishing site: https://www.packtpub.com/application-development/hands-typescript-c-and-net-core-developers.

Succinctly Series Readers Awards

image

My e-book Entity Framework Core Succinctly was silver winner on the Succinctly Series Readers Awards!

Many thanks to all who voted for it! And congratulations to Joseph D. Booth for winning the gold award for his Natural Language Processing Succinctly and to Alessando Del Sole (@progalex) for his bronze award for Xamarin.Forms Succinctly!

https://www.syncfusion.com/awards/succinctlyseries/2018succinctlyreadersawards

.NET Core Service Provider Gotchas and Less-Known Features

Introduction

In this post I’m going to talk about a few gotchas with the .NET Core’s built-in inversion of control (IoC) / service provider (SP)/dependency injection (DI) library. It is made available as the Microsoft.Extensions.DependencyInjection NuGet package.

I wrote another post some time ago, but this one supersedes it, in many ways.

Extension Methods

The single method exposed by the IServiceProvider interface, GetService, is not strongly typed. If you add a using statement for Microsoft.Extensions.DependencyInjection, you’ll get a few ones that are:

  • GetRequiredService<T>: tries to retrieve a service that is registered under the type of the generic template parameter and throws an exception if one cannot be found; if it is, it is cast to the template parameter;
  • GetService<T>: retrieves a service and casts it to the template parameter; if no service is found, null is returned;
  • GetServices<T>: returns all services registered as the template parameter type, cast appropriately.

Using a Different Service Provider

You are not forced to use the built-in service provider; you can use anyone you like, as long as it exposes an IServiceProvider implementation. You just need to return this implementation from the ConfigureServices method, which normally does not return anything:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
//return an implementation of IServiceProvider
}

Why would you want to do that, you may ask? Well, there are service providers out there that offer much more interesting features than Microsoft’s (for example, more lifetimes), and this has a reason: Microsoft kept his simple on purpose.

Multiple Registrations

You may not have realized that you can register any number of implementations for a given service, even with different lifetimes:

services.AddTransient<IService, ServiceA>();
services.AddScoped<IService, ServiceB>();

So, what happens when you ask for an implementation for IService? Well, you get the last one registered, in this case, ServiceB. However, you can ask for all the implementations, if you call GetServices<T>.

Registration Factories

You can specify how a service implementation is constructed when you register a service, and it can depend upon other services that are also registered in the service provider:

services.AddTransient<IService>(sp => new ServiceImpl(sp.GetRequiredService<IOtherService>));

Don’t worry about registration order: IOtherService will only be required once IService is retrieved.

Lifetime Dependencies

You cannot have a Singleton registration depend upon a Scoped service. This makes sense, if you think about it, as a singleton has a much longer lifetime than a scoped service.

Nested Scopes

You can create nested scopes at any time and retrieve services from them. If you are using the extension methods in the Microsoft.Extensions.DependencyInjection namespace, it’s as easy as this:

using (var scope = serviceProvider.CreateScope())
{
    var svc = scope.ServiceProvider.GetRequiredService<IService>();
}

The CreateScope method comes from the IServiceScopeFactory implementation that is registered automatically by the dependency injection implementation. See next for implications of this.

Why is this needed? Because of lifetime dependencies: using this approach you can instantiate a service marked as a singleton that takes as a parameter a scoped one, inside a scope.

Dispose Pattern

All services instantiated using the Scoped or Transient lifetimes that implement the IDisposable interface will have their Dispose methods called at the end of the request – or the nested scope (when it is disposed). The root service provider is only disposed with the app itself.

Scope Validation

The built-in service provider validates the registrations so that a singleton does not depend on a scoped registration. This has the effect of preventing retrieving services in the Configure method, through IApplicationBuilder.ApplicationServices, that are not transient or singletons.

If, however, you think you know what you’re doing, you can bypass this validation:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
//add services
return services.BuildServiceProvider(validateScopes: false);
}

As I said before, the other alternative is creating a scope and instantiating your singleton service inside the scope. This will always work.

Injecting Services

ASP.NET Core only supports constructor:

public HomeController(IService svc)
{
}

and parameter:

public IActionResult Index([FromServices] IService svc)
{
}

inheritance, but not property, in controllers and Razor Pages. You can achieve that through actions or conventions. Another option is to use the Service Locator pattern.

Service Locator

You can retrieve any registered services from HttpContext.RequestServices, so whenever you have a reference to an HttpContext, you’re good. From the Configure method, you can also retrieve services from IApplicationBuilder.ApplicationServices, but not scoped ones (read the previous topics). However, it is generally accepted that you should prefer constructor or parameter injection over the Service Locator approach.

Conclusion

Although the service provider that comes with .NET Core is OK for most scenarios, it is clearly insufficient for a number of others. These include:

  • Other lifetimes, such as, per resolve-context, per thread, etc;
  • Property injection;
  • Lazy<T> support;
  • Named registrations;
  • Automatic discovery and configuration of services;
  • Child containers.

You should consider a more featured DI library, and there are many out there, if you need any of these.

Integrating Managed Extensibility Framework with the .NET Service Provider

Introduction

It seems I’m in the mood for Managed Extensibility Framework: second post in a week about it! This time, I’m going to talk about how we can integrate it with the .NET Core’s service provider/dependency injection (DI) library (Microsoft.Extensions.DependencyInjection).

Mind you, this will apply to both ASP.NET Core and .NET Core console apps.

Locating Services

We’ve seen before how we can find all types that match a given interface:

public static class ContainerConfigurationExtensions     {         public static ContainerConfiguration WithAssembliesInPath(this ContainerConfiguration configuration, string path, SearchOption searchOption = SearchOption.TopDirectoryOnly)         {             return WithAssembliesInPath(configuration, path, null, searchOption);         }         public static ContainerConfiguration WithAssembliesInPath(this ContainerConfiguration configuration, string path, AttributedModelProvider conventions, SearchOption searchOption = SearchOption.TopDirectoryOnly)         {             var assemblyFiles = Directory                 .GetFiles(path, "*.dll", searchOption);             var assemblies = assemblyFiles                 .Select(AssemblyLoadContext.Default.LoadFromAssemblyPath);             configuration = configuration.WithAssemblies(assemblies, conventions);             return configuration;         }     }

Service Registration

The next step is picking up all of the found types and registering them with the DI:

public static class ServiceCollectionExtensions     {         public static IServiceCollection AddFromAssembliesInPath<T>(this IServiceCollection services, ServiceLifetime lifetime, string path = null) where T : class         {             var factory = new ExportFactory<T, object>(() => new Tuple<T, Action>(Activator.CreateInstance<T>(), () => { }), new object());             var conventions = new ConventionBuilder();             var builder = conventions                 .ForTypesDerivedFrom<T>()                 .Export<T>();             if (lifetime == ServiceLifetime.Singleton)             {                 builder = builder.Shared();             }             path = path ?? AppContext.BaseDirectory;             var configuration = new ContainerConfiguration()                 .WithAssembliesInPath(path, conventions);             using (var container = configuration.CreateContainer())             {                 var svcs = container.GetExports<Lazy<T>>();                 foreach (var svc in svcs)                 {                     services.Add(new ServiceDescriptor(typeof(T), sp => svc.Value, lifetime));                 }             }             return services;         }         public static IServiceCollection AddSingletonFromAssembliesInPath<T>(this IServiceCollection services, string path = null) where T : class         {             return AddFromAssembliesInPath<T>(services, ServiceLifetime.Singleton, path);         }         public static IServiceCollection AddScopedFromAssembliesInPath<T>(this IServiceCollection services, string path = null) where T : class         {             return AddFromAssembliesInPath<T>(services, ServiceLifetime.Scoped, path);         }         public static IServiceCollection AddTransientFromAssembliesInPath<T>(this IServiceCollection services, string path = null) where T : class         {             return AddFromAssembliesInPath<T>(services, ServiceLifetime.Transient, path);         }     }

The AddFromAssembliesInPath extension method is what does all the work; it leverages the previous WithAssembliesInPath method to locate all types that match a given interface, in the assemblies inside a specific folder (which can be the current one). AddSingletonFromAssembliesInPath, AddScopedFromAssembliesInPath and AddTransientFromAssembliesInPath are merely here to make your life a (little bit) easier. Although MEF only supports singletons (Shared) and transient (Non-shared) lifetimes, with this approach

Notice how MEF let’s us resolve Lazy<T> instances besides T. This is pretty cool, as we can delay object instantiation to a later stage, when the object is actually needed. A word of caution: the instantiation will actually be done by MEF, not by the .NET Core DI, so you won’t have constructor injection.

Putting it all Together

So, armed with these two extension methods, we can add this to the ConfigureServices method of your ASP.NET Core app (or wherever you populate your service provider):

services.AddTransientFromAssembliesInPath<IPlugin>();

Here IPlugin is just some interface, nothing to do with the one described in the previous post. After this, you should be able to inject all of the actual implementations:

public class HomeController : Controller

{

public HomeController(IEnumerable<IPlugin> plugins) { … }

}