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