Using Microsoft Fakes with mscorlib.dll


Microsoft Fakes is a tool that allows you to replace any method of any .NET class. This makes it ideal for testing untestable code, for example code that uses DateTime.Now in its implementation...

However when using Microsoft Fakes with mscorlib.dll, the assembly that contains DateTime, you will encounter an error Error CS0234:

The type or namespace name 'EventSourceCreatedEventArgs' does not exist in the 
namespace 'System.Diagnostics.Tracing' (are you missing an assembly reference?)

This actually should not be a problem, because it is actually a sign of something else: that you're faking too much (no pun intended :). Using Microsoft Fakes will generate a fake type for every type in the target assembly, which is very wastefull of resources. You should actually only fake the type you're testing.

Open the fakes file (for example mscorlib.fakes):

<Fakes xmlns="http://schemas.microsoft.com/fakes/2011/">
  <Assembly Name="mscorlib" Version="4.0.0.0"/>
  <StubGeneration>
    <Clear />
  </StubGeneration>
  <ShimGeneration>
    <Clear />
    <Add FullName="System.DateTime!" />
  </ShimGeneration>
</Fakes>

As you can see here, you add each type you want to stub/shim in the <StubGeneration> and <ShimGeneration> section.

For more information about this, you can find more documentation at https://msdn.microsoft.com/en-us/library/hh708916.aspx#BKMK_Configuring_code_generation_of_stubs

Using Razor outside of MVC for building custom middleware or other generation stuff

Recently I have been building some asp.net core middleware which involves generating some html from a collection of elements.

Writing code to generate html is no fun at all, so I decided to see if I could not use Razor outside of the normal MVC stack.

Simple answer: yes! 

I've published this as a package on NuGet.org (scroll down for sources):

U2U.AspNetCore.Mvc.Razor

Use razor to generate files outside of the normal MVC Controller/View chain, for example in your middleware, or for sending dynamic email messages.

All you need is a HttpContext.

To generate contents from Razor as a string

Start by creating a viewModel instance. The ViewModel is used to pass data to the Razor file, ViewData or ViewBag is not supported.

Create a Razor file, using the ViewModel's class as the @model:

@model TestRazor.Models.RazorViewModel

Your message: @Model.Message

Then call the RenderToStringAsync method (which is an extension method on HttpContext) passing the path to the razor file and the viewmodel. You will get the result back as a string.

var viewModel = new RazorViewModel { Message = "Generated from razor!" };
var contents = await HttpContext.RenderToStringAsync("~/Views/Home/Razor.cshtml", viewModel);

To generate Razor contents to the response stream

Start by creating a viewModel instance. The ViewModel is used to pass data to the Razor file, ViewData or ViewBag is not supported.

Create a Razor file, using the ViewModel's class as the @model:

@model IEnumerable<U2U.AspNetCore.NotFound.NotFoundRequest>

<!DOCTYPE html>
<html>
<body>
  <h1>Fix 404s</h1>
  <table>
    <thead id="requestHeader">
      <tr>
        <th class="path">Path</th>
        <th>404 Count</th>
        <th>Corrected Path</th>
      </tr>
    </thead>
    <tbody>
      @foreach (var request in Model)
      {
        <tr class="requestRow">
          <td>@request.Path</td>
          <td>@request.Hits</td>"
          @if (!String.IsNullOrEmpty(request.FixedPath))
          {
          <td>@request.FixedPath</td>
          }
          else
          {
          <td>
            <input type="text" />
            <a href='@string.Format("?path={0}&fixedPath=", request.Path)' class="fixLink">Save</a>
          </td>
          }
        </tr>
        }
      </tbody>
    </table>
  </body>
</html>

Then call the RenderToStringAsync method (which is an extension method on HttpContext) passing the path to the razor file and the viewmodel. The resulting razor content is written to the result stream.

var viewModel = tracker.NotFoundRequests.OrderByDescending(r => r.Hits).ToList();
await context.RenderAsync("~/Views/Shared/NotFound.cshtml", viewModel);

Sources

Sources of this package are available on github repository https://github.com/PeterHimschoot/U2U.AspNetCore.Mvc.Razor

Any bugs, remarks, etc... can always be sent to peter@u2u.be

Simpler checking of arguments with C# 7 throw expressions

Simpler checking of arguments with C# 7 throw expressions

C# 7 has made a simple and important change to C# throw statements. They are now expressions.

So what does that mean for you? It means that now you can check your arguments with a simpler statement.

One such recurring pattern is in the constructor of a class, where you get passed some mandatory dependency. This dependency cannot be null, and then needs to be stored. If the dependency is null, you want to throw an ArgumentNullException.

Here is an example in C# 6

if( context != null )
{
  throw new ArgumentNullException(nameof(context));
}
this.context = context;

Compare this with the C# 7 version:

this.context = context ?? throw new ArgumentNullException(nameof(context));

We assign the context field a value with the null-coalescing operator which takes the left side if it is null (and doesn't evaluate the right side). If the left side is null, it evaluates the right side, which throws an ArgumentNullException.

Way simpler and elegant!

Markdown taghelper

U2U.AspNetCore.Mvc.TagHelpers

Markdown MVC6 taghelper

This taghelper will replace itself with markdown converted to html.

You can learn more about this handy syntax here: https://daringfireball.net/projects/markdown/

You can choose between

  • Path to a markdown file on disk
  • Url to markdown contents
  • Embedded markdown

To convert a local markdown file to html:

<md path="~/md/demo.md">
</md>

To convert some markdown content from the internet use:

<md href="https://applephi.blob.core.windows.net/demo/README.md">
</md>

And of course you can simply embed markdown:

<md class="row">
  ## This is a test

  This is a test

  ```
  With some code
  ```
</md>

Sources

I you're interested in how this packages works, it is available on github at https://github.com/PeterHimschoot/U2U.AspNetCore.Mvc.TagHelpers

Any bugs, remarks, etc... can always be sent to peter@u2u.be

Getting rid of "String based programming" style in dotnet core

String based programming

I really don't like the coding style of using strings instead of identifiers... For example in MVC you can redirect to another action using

RedirectToAction("Index");

However, using the string "Index" instead of the name of the method (an action typically corresponds to a method in MVC right?!) make your code harder to maintain. Renaming the method will not rename the string for example. That is why I like to use

RedirectToAction(nameof(HomeController.Index))

However, this does not work with Controller names. Because of the way routing is implemented, using the full name of the controller confuses routing and you end up with an invalid Uri.

RedirectToAction(nameof(HomeController.Index), nameof(HomeController))

This problem is fixed by U2U.AspNetCore.Mvc.NameOf

U2U.AspNetCore.Mvc.NameOf

This package updates Mvc6 to allows the use of the nameof() keyword in your views

For example, instead of using strings for the name of the controller and action

<a asp-controller="Home" asp-action="Index" class="navbar-brand">Index</a>

you can use nameof()

<a asp-controller="@nameof(HomeController)" asp-action="@nameof(HomeController.Index)" class="navbar-brand">Index</a>

Setup

All you need to do extra is to add a using to your _ViewImports.cshtml

@using WebApplication2.Controllers

and in Startup.ConfigureServices add a call to AddNameOf after the call to AddMvc.

services.AddMvc();
services.AddNameOf();

Sources

I you're interested in how this packages works, it is available on github at https://github.com/PeterHimschoot/U2U.AspNetCore.Mvc.NameOf

Any bugs, remarks, etc... can always be sent to peter@u2u.be

Building the angular.io quickstart with ASP.NET Core

When you start to explore angular 2, probably the best place to start is taking the quick start on angular.io.

In this post I will show you how you can setup the project to use Visual Studio 2015 and ASP.NET Core, since the quick start from angular.io doesn't work as described with ASP.NET Core. Some of the changes are different conventions (putting the libraries in the wwwroot/lib folder for example), and some changes are because we will be using gulp...

 

I will give you step by step instructions on how to setup the project, explanations about why can be found on angular.io.

 

Start by creating a new ASP.NET Core project in Visual Studio:

image

Click OK. In the next screen pick the Empty template.

Open project.json and add a dependency to the StaticFiles package:

"dependencies": {
  "Microsoft.NETCore.App": {
    "version": "1.0.0",
    "type": "platform"
  },
  "Microsoft.AspNetCore.Diagnostics": "1.0.0",
 
  "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
  "Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
  "Microsoft.Extensions.Logging.Console": "1.0.0",
  "Microsoft.AspNetCore.StaticFiles": "1.0.0"
},

Save your changes so NuGet will install the package.

Open Startup.cs and add the StaticFiles middleware:

app.UseDefaultFiles(new DefaultFilesOptions
{
  DefaultFileNames = new string[] { "index.html" }
});
app.UseStaticFiles();

Now add a new JSON file to the project (next to project.json) called package.json:

{
  "name": "angular2-quickstart",
  "version": "1.0.0",
  "scripts": {
    "postinstall": "typings install",
    "typings": "typings"
  },
  "license": "ISC",
  "dependencies": {
    "@angular/common": "2.0.0-rc.5",
    "@angular/compiler": "2.0.0-rc.5",
    "@angular/core": "2.0.0-rc.5",
    "@angular/forms": "0.3.0",
    "@angular/http": "2.0.0-rc.5",
    "@angular/platform-browser": "2.0.0-rc.5",
    "@angular/platform-browser-dynamic": "2.0.0-rc.5",
    "@angular/router": "3.0.0-rc.1",
    "@angular/router-deprecated": "2.0.0-rc.2",
    "@angular/upgrade": "2.0.0-rc.5",
    "angular2-in-memory-web-api": "0.0.15",
    "bootstrap": "^3.3.6",
    "core-js": "^2.4.0",
    "reflect-metadata": "^0.1.3",
    "rxjs": "5.0.0-beta.6",
    "systemjs": "0.19.27",
    "zone.js": "^0.6.12"
  },
  "devDependencies": {
    "typescript": "^1.8.10",
    "gulp": "^3.9.1",
    "path": "^0.12.7",
    "gulp-clean": "^0.3.2",
    "gulp-concat": "^2.6.0",
    "gulp-typescript": "^2.13.6",
    "typings": "^1.3.1",
    "gulp-tsc": "^1.2.0"
  }
}
Save this file to make visual studio do a npm install.
 
image
 

Add another JSON file called typings.json

{
  "globalDependencies": {
    "core-js": "registry:dt/core-js#0.0.0+20160602141332",
    "jasmine": "registry:dt/jasmine#2.2.0+20160621224255",
    "node": "registry:dt/node#6.0.0+20160807145350"
  }
}
Right-click the Dependencies folder and choose Restore packages. This will install the typings.
 
Now add a gulp configuration file (gulpfile.js):
var ts = require('gulp-typescript');
var gulp = require('gulp');
var clean = require('gulp-clean');
var destPath = './wwwroot/lib/';
// Delete the dist directory
gulp.task('clean', function () {
  return gulp.src(destPath)
      .pipe(clean());
});
gulp.task("scriptsNStyles", () => {
  gulp.src([
          'core-js/client/**',
          'systemjs/dist/system.src.js',
          'reflect-metadata/**',
          'rxjs/**',
          'zone.js/dist/**',
          '@angular/**',
          'jquery/dist/jquery.*js',
          'bootstrap/dist/js/bootstrap.*js',
  ], {
    cwd: "node_modules/**"
  })
      .pipe(gulp.dest(destPath));
});
var tsProject = ts.createProject('app/tsconfig.json');
gulp.task('ts', function (done) {
  //var tsResult = tsProject.src()
  var tsResult = gulp.src([
          "app/*.ts"
  ])
      .pipe(ts(tsProject), undefined, ts.reporter.fullReporter());
  return tsResult.js.pipe(gulp.dest('./wwwroot/app'));
});
gulp.task('watch', ['watch.ts']);
gulp.task('watch.ts', ['ts'], function () {
  return gulp.watch('app/*.ts', ['ts']);
});
gulp.task('default', ['scriptsNStyles', 'watch']);

Open Task Runner Explorer and run the default task (you might need to refresh it first).

This will setup a watch that will look for typescript (.ts) files in the app folder of your project, compile them and then copy them into wwwroot/app.

Time to add this app folder, so right-click your project, choose Add New Folder, and name it app:

In it add the TypeScript Configuration file (tsconfig.json):

{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "module": "commonjs",
    "noEmitOnError": true,
    "noImplicitAny": false,
    "removeComments": false,
    "sourceMap": true,
    "target": "es5",
    "moduleResolution": "node"
  },
  "exclude": [
    "node_modules",
    "typings/index",
    "typings/index.d.ts"
  ]
}

NOTE: If you don't like the compiler output to end up in your source folder you can actually use the outDir to put them somewhere else, for example:

    "outDir": "../wwwroot/app/"

Now add a new TypeScript file called app.component.ts:

NOTE: If you get compile errors, right-click the Node Dependencies folder and restore them.

import { Component } from '@angular/core';
@Component({
  selector: 'my-app',
  template: '<h1>My First Angular 2 App</h1>'
})
export class AppComponent { }
Add another TypeScript file called app.module.ts:
///<reference path="./../typings/globals/core-js/index.d.ts"/>
import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent }  from './app.component';
@NgModule({
  imports: [BrowserModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class AppModule { }
Add another one called main.ts:
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
Almost there...
 
Open wwwroot and look for (or create) the js folder.
Add a new javascript file in this folder called systemjs.config.js:
/**
* System configuration for Angular 2 samples
* Adjust as necessary for your application needs.
*/
(function (global) {
  // map tells the System loader where to look for things
  var map = {
    'app': 'app', // 'dist',
    '@angular': 'lib/@angular',
    'angular2-in-memory-web-api': 'lib/angular2-in-memory-web-api',
    'rxjs': 'lib/rxjs'
  };
  // packages tells the System loader how to load when no filename and/or no extension
  var packages = {
    'app': { main: 'main.js', defaultExtension: 'js' },
    'rxjs': { defaultExtension: 'js' },
    'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
  };
  var ngPackageNames = [
    'common',
    'compiler',
    'core',
    'forms',
    'http',
    'platform-browser',
    'platform-browser-dynamic',
    'router',
    'router-deprecated',
    'upgrade',
  ];
  // Individual files (~300 requests):
  function packIndex(pkgName) {
    packages['@angular/' + pkgName] = { main: 'index.js', defaultExtension: 'js' };
  }
  // Bundled (~40 requests):
  function packUmd(pkgName) {
    packages['@angular/' + pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
  }
  // Most environments should use UMD; some (Karma) need the individual index files
  var setPackageConfig = System.packageWithIndex ? packIndex : packUmd;
  // Add package entries for angular packages
  ngPackageNames.forEach(setPackageConfig);
  var config = {
    map: map,
    packages: packages
  };
  System.config(config);
})(this);
This file differs from the one on angular.io in where it will look for things (lib instead of node_modules)...
Now add a html file under the wwwroot folder called index.html:
<html>
<head>
    <title>Angular 2 QuickStart</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="css/styles.css">
    <!-- 1. Load libraries -->
    <!-- Polyfill(s) for older browsers -->
    <script src="lib/core-js/client/shim.min.js"></script>
    <script src="lib/zone.js/dist/zone.js"></script>
    <script src="lib/reflect-metadata/Reflect.js"></script>
    <script src="lib/systemjs/dist/system.src.js"></script>
    <!-- 2. Configure SystemJS -->
    <script src="js/systemjs.config.js"></script>
    <script>
      System.import('app').catch(function(err){ console.error(err); });
    </script>
</head>
<!-- 3. Display the application -->
<body>
    <my-app>Loading...</my-app>
</body>
</html>
And don't forget to add a .css style (web developers always have style right?!).
Create a css folder under wwwroot, and add a css file called styles.css:
h1 {
  color: #369;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 250%;
}
body {
  margin: 2em;
}
 

Hit F5 to run your angular 2 web site. If all goes well you should see:

image

And if you want to learn a lot more about Angular 2, we have an excellent training on it!

Using nameof() in MVC6 razor views

C# 6 introduces the new nameof() operator, which allows you to embed the name of a class, method or property easily into your code without degrading to string-based programming... String-based programming is where you use strings, where it would be better to use code...

Razor is one of those places where there are too many strings. For example, using the new tag-helpers:

<a asp-controller="HomeController" asp-action="About">About</a>

A better, more maintainable way of doing this would be

<a asp-controller="@nameof(HomeController)" asp-action="@nameof(HomeController.About)">About</a>

You might ask why? Because, for example, renaming the About method will result in Visual Studio renaming the method in your Razor views too! And if you have a typo, the compiler will warn you. That is why!

However, out of the box MVC6 does not allow this. So I've written and published a NuGet package that allows you to use this nameof() operator in MVC6 razor views.

Simply add it to your project's dependencies in project.json:

"dependencies": {
  ...
  "U2U.NameOf": "1.0.0"
}

Add the namespace of your controllers to _ViewImports.cshtml:

@using <YourProject>.Controllers

Finally open Startup.cs and add a using statement:

using U2U;

and in the ConfigureServices method add :

services.AddMvc();
services.AddNameOf();

Now open _Layout.cshtml and change all your archors to use nameof(...):

<a asp-controller="@nameof(HomeController)" asp-action="@nameof(HomeController.Index)">

You can also use this with the old-style Html helper methods:

@Html.ActionLink("test", nameof(HomeController.Contact), nameof(HomeController))

and also in code:

Url.Action(action: nameof(HomeController.About), controller: nameof(HomeController));

I hope you like it!

Next blog post will explain how it works.

.NET Core 5 event

So yesterday at U2U we had a little Post-/BUILD event, where I did a session on the new stuff in Visual Studio 2015, such as C# 6, .NET Core 5, and ASP.NET 5.

Anyone interested in the slides I used can find them here.

Slides.pdf (648.3KB)

ASP.NET 5 Configuration

So I've been playing around with ASP.NET 5 and of course I encountered the new configuration model. And a lot of things are nicely documented. But one thing I could not find on the internet (maybe I am just bad at binging/googling): how to get these configuration settings in your controller/viewmodel.

So what is the problem? For starter you setup your configuration(s) in the Startup class, for example:

public Startup(IHostingEnvironment env)
{
  var configuration = new Configuration().AddJsonFile("config.json");
  Configuration = configuration;
}

This code sets the configuration as the Startup class's Configuration property. This property is not easily accessible in your Controller, which is a good thing.

What?! A good thing? Yes, because it you should not use Configuration directly anywhere else. Dependency Injection to the rescue!

First thing you want to do is to think about which configuration settings you need (per viewmodel/controller), and then wrap this into a class:

public class MemConfig
{
  public string FromMem1 { get; }
  public string FromMem2 { get; }
}

This example will wrap two settings from configuration.

Now I want need these settings in my viewmodel (or controller, same technique), so we will add the MemConfig class to the viewmodel as a dependency:

private MemConfig mem;

public ConfigurationViewModel(MemConfig mem)
{
  this.mem = mem;
}

Now we only need to tell dependency injection how to create MemConfig. We do this again in the Startup class:

public void ConfigureServices(IServiceCollection services)
{
  services.AddSingleton<MemConfig>((isp) =>
   new MemConfig
   {
      FromMem1 = Configuration["FromMem1"],
      FromMem2 = Configuration["FromMem2"]
   });
   services.AddTransient<ConfigurationViewModel>();
}

So how does this work. Each time my controller needs a viewModel I make DI inject my viewmodel into the controller. The viewmodel also has a dependency, so DI will inject a MemConfig instance into the viewmodel.

I configured DI to use a singleton instance for the MemConfig class, and I told it how it should be initialized from Configuration. This last part is centralized in the Startup class, and we don't need any specific configuration logic anywhere else.


What I remember about /Build 2015


The excitement was there again, in San Francisco, where Microsoft displayed their latest innovations, to us, humble developers.

So what do I remember from /Build? That Microsoft is really going cross-platform. It is now possible to develop on Windows with Visual Studio, but now you can also create .NET applications and web sites on Linux and Mac on .NET core using the brand new Visual Studio Code editor. To enable this they've build a new execution environment (DNX). 


For building ASP.NET 5 web sites Microsoft has integrated bower (which is a javascript package manager), gulp (a javascript task manager, for example to minimize your .css and .js files) and grunt (another task manager) into Visual Studio. What this means to us developers is that you can choose: you can develop on Windows with Visual Studio, or you can develop on Windows/Mac/Linux with your choice of tools. You can mix, someone using Visual Studio, someone not... it's up to you.


On the Windows 10 front, Microsoft now has a unified stack for building apps on desktop, tablet, phone, ... Of course not every device has the same capabilities.. This used to mean conditional compilation (!?). Now, in Windows 10, there are libraries that allow you to check if some capability is there (for example camera) and if it is not, the library still has stubs to the methods, except they don't do anything. This means one binary for all devices. But this was already common knowledge. 


Closing the "app gap": Microsoft showed a demo with a simple iOS game being recompiled into a Windows Phone app. Yes, take an Objective-C application (no Swift support) and recompile it to a Windows 10 app! And you can do the same for an Android app! Amazing! The question remains: how far can you take this? Are all standard iOS/Android libraries supported? Time will tell. I really hope that Microsoft can make all of this work.


Run your web site as a Windows 10 app: Microsoft also demonstrated that you can take your web site (I think this will only work for ASP.NET based web sites) and wrap it into an app, then modifying the web site to take advantage of Windows 10 features.


What really excited me at /Build was Windows 10 Continuum. Just imagine, you walk into your office, take out your phone and place it on your desktop. The keyboard, mouse and screen on your desktop connect to your phone, allowing you to continue working on your phone, but now with a full desktop experience. Later, going home, you take your phone with you and you can continue working on it on the train, except of course now you have the small screen experience. No more carrying around a bulky device!


Project Spartan, which is an internal name, now got its real name: Microsoft Edge. This new browser is available in the latest Windows 10 insider build. I ran it against html5test and got a score of 390. It looks like they still have some work to do, but hey, this is preliminary software...



Team Build has been redesigned. Anyone ever needing to customize team build will testify that using XAML based Workflow Foundation to describe the build process was far from simple. Adding custom steps was even harder... Now Microsoft has made it really simple to customize builds using tasks:

Easy customization

Including cross-platform tasks out-of-the-box:

Cross-platform builds

What is also really neat is the ability to compare the build definitions, so you can figure out what was modified in that build definition:

View the details


Microsoft has done a lot of work to integrate docker into azure. If you have no idea what docker is, look here. In a nutshell it allows you to take your code, wrap it into a container and that run that container anywhere... You can then connect your container with other containers to make things happen. You can also build workflows from containers...


Companies with a lot of small databases will be happy to learn that they can now save costs with Azure SQL Database elastic databases. I think (sorry) that it allows you to pool your databases into one database server (still nicely separated into your tenants) and configure the minimal cpu requirements for each database.  I'm not that into database stuff so more about this here.


The star of the show: HoloLens. This kind of -- almost science fiction -- hardware makes a lot of people drool. Of course! Allowing people to run inside a virtual environment and react with it. Architects, product designers, game builders, the applications -- once they become available -- will open up a whole new world.
Some people had the luck to try it out for themselves, I was not one of them :( 
But my colleague was, and his major comment was that it did not track where you were looking, it tracked where HoloLens was looking. I think they will have to work on iris tracking -- hoping the HoloLens device won't cost as much as a jet fighter's helmet :)