The New Fetch Standard

Monday, February 8, 2016 by K. Scott Allen

The XMLHttpRequest object has been around, in one form or another, since 1999. XHR has been a key ingredient in most web applications for well over a decade now. During that time various libraries have wrapped the API to make XHR more palatable and easier to use, while vendors have extended the capabilities of XHR to support binary data, cross origin requests, and progress events. It’s been quite the ride, but the future is fetch.

Think of fetch as a modernized XMLHttpRequest. The raw API is easier to use, and all starts with a global fetch method.

var movie = {
    id: 1,
    title: "Star Wars"
};

fetch("/movies", {
    method: "put",
    headers: {
        "Content-Type": "application/json"
    },
    body: JSON.stringify(movie)
}).then(function(response) {
    return response.text()
}).then(function(result)) {
     console.log(result);
});
    

With promises now an official part of the JavaScript language, it is nice to see standard APIs using promises instead of callbacks.

Browser support for fetch is coming along (I ran the above sample in Chrome 47), although the API is still a work in progress. The API allows us to influence the caching mode directly ({cache:”reload”}, as one example), which is good, but timeouts and deadlines are still open issues and not yet in the spec.

Some of My Favorite Maps

Friday, February 5, 2016 by K. Scott Allen

I remember being a kid in the back seat of my parents car on a 10 hour jaunt to Indiana when I first discovered the joys of a Rand McNally Road Atlas. I used to keep track of our progress along the highway, but also trace routes to destinations I’d only heard of, and marvel at the complexity of inner city road systems. I think the experience was good for me as today I have a decent sense of direction. I also learned, years before driving myself, that odd numbered roads in the US typically run north and south, while even numbered roads run east and west. Later in life I learned to ignore all directional conventions when in southern New Jersey.

Most of the maps I use today aren’t as tactile as the old road atlas, but I still find maps educational and in some ways, inspirational, too. Here are a few places I keep bookmarked.

Wikimapia

Wikimapia combines the the imagery and cartography of Google and Bing with peer-produced content ala Wikipedia. The older I get the more I’m interested in the history of the places I visit, and Wikimapia is starting point for location-based research. On my last trip I investigated the Canary Wharf district of London and tried to find out why the district is on a piece of land known as the Isle of Dogs, but there are only hypotheses about the etymology of the name. Canary Whaf in Wikimapia

Earth

A globe built with SVG and canvas elements provides a visualization of winds, weather systems, and ocean currents. Use the menu in the lower left to see everything from surface winds to ocean waves and jet steams including, at this time of year, the polar night jet.

Source code is available from Cameron Beccario on github.

image

Flightradar24

A real-time flight tracker. Ideal for those situations when you want to know who is flying overhead

Flightradar24

MarineTraffic

A real-time vessel tracker. Ideal for those situations when you want to know who is sailing nearby.

MarineTraffic

Wundermap

The weather map from the Weather Underground is the first map I check for weather conditions. Not only can you fill the map full of information, the web site itself doesn’t use terrifying headlines and bizarre ads like some other weather sites.

Weather Undergrounds Wundermap

Extending Razor Views in ASP.NET Core

Thursday, February 4, 2016 by K. Scott Allen

If you need to add capabilities to Razor views in ASP.NET Core, there are a few different approaches you can take.

@inherits

By default, a Razor view inherits from RazorPage<T>, where T is the type of model as set by the @model directive. With no XML based configuration around, the @inherits directive is now available to change the default base class. Currently, @inherit only appears to work when the base class of the base class is RazorPage<object>, but using a custom base class does give you the ability to define additional properties and methods for a view to consume.

@inherits BaseView
<div>
    ...
</div>
public abstract class BaseView : RazorPage<object>
{              
    public bool IsAuthenticated()
    {
        return Context.User.Identity.IsAuthenticated;
    }
}

Note that one downside to @inherits (other than encouraging a messy inheritance hierarchy) is that the @inherits and @model directives are mutually exclusive, so you can’t use both in the same view. Thus, the “one base class to rule them all” approach is unfeasible. Fortunately, there are better approaches.

@functions

The @functions directive is similar to the @helper directive in previous versions of Razor. ASP.NET generates a class after parsing a view, and code inside of the @functions block are added as members to the class. In most cases you’ll want to add only functions to the generated class, but it is technically possible to add fields, properties, and events.

@functions
{
    public bool IsAuthenticated()
    {
        return Context.User.Identity.IsAuthenticated;
    }

    readonly string message = “test”;
}

<div>
    @if (IsAuthenticated())
    {
        <div>...</div>
    }
    else
    {
        <div>@Message</div>
    }
</div>

Currently there doesn’t appear to be an easy way to share @function blocks across multiple views, but there is one more option, which is, I think, the best option.

@inject

The @inject directive creates a new property in the generated code for a view. ASP.NET will set the property by asking the IoC container for a service that matches the type of the property. With the following Razor code, we’ll inject the IHostingEnvironment service which is available in every web application by default, and use the service to display the current environment name.

@inject IHostingEnvironment Host;


<div>
    Running in @Host.EnvironmentName
</div>

The class ASP.NET generates for a view with an @inject directive looks like the following:

[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public IHostingEnvironment Host { get; private set; }

You might see @inject as an abuse of the MVC design pattern. Why inject services directly into a view when I could use the same services inside a controller and build a proper model in a testable manner? A fair criticism, and ‘@inject abuse’ will be a design flaw to avoid. However, a view does need to execute code and there are a reasonable set of services that can help a view. For example, a localization service. In fact, several in-built capabilities of Razor views are injected as services by default, like the Url, Html, and Component helpers. You’ll find the following properties in the code by default for every Razor generated view.

[RazorInjectAttribute]
public IUrlHelper Url { get; private set; }

[RazorInjectAttribute]
public IViewComponentHelper Component { get; private set; }

[RazorInjectAttribute]
public IJsonHelper Json { get; private set; }

[RazorInjectAttribute]
public IHtmlHelper<dynamic> Html { get; private set; }

Having an IUrlHelper injected into a view instead of being inherited from a base class means we are using composition instead of inheritance, which gives us more flexibility and extensibility points than ever before.

But wait, there’s more!

@inject and _ViewImports

ASP.NET core adds a new magic file by the name of _ViewImports. Similar to _ViewStart, this is a file that when placed into a folder will influence all views in the folder hierarchy. One reason for _ViewImports to exist is to provide some default using statements to bring namespaces into scope for all views in the same hierarchy (again, because we have no XML configuration to work with and XML is where we used to specify default namespaces). However, you can also use _ViewImports to register tag helpers, and the @inject attribute also works from _ViewImports. Let’s say you place the following code into a _ViewImports.cshtml file in the Views folder itself. The namespaces and injected properties are available for every view in the Views folder, and all child folders.

@* These namespaces now available to all views *@
@using Microsoft.AspNet.Hosting

@* These services now available to all views *@
@inject IMyViewHelpers Helpers;
@inject IHostingEnvironment Host;

Summary

Forget @functions and don’t use @inherits. The @inject directive allows you to compose functionality into Razor views in a flexible, extensible, and testable manner.

Spying on Razor View Compilation

Wednesday, February 3, 2016 by K. Scott Allen

Sometimes the best way to understand code is to compile and execute the code. In this scenario I needed to understand a bit more about view compilation in ASP.NET Core. Here is a simple spy to track the file information and compilation results for each razor view.

public class RazorCompilationServiceSpy : IRazorCompilationService
{
    private IRazorCompilationService _inner;
    private IList<CompileEntry> _log;

    public RazorCompilationServiceSpy(ICompilationService compilationService,
                                      IMvcRazorHost razorHost, 
                                      IOptions<RazorViewEngineOptions> options)
    {
        _inner = new RazorCompilationService(compilationService, razorHost, options);
        _log = new List<CompileEntry>();
    }

    public CompilationResult Compile(RelativeFileInfo fileInfo)
    {
        var result = _inner.Compile(fileInfo);
        _log.Add(new CompileEntry { FileInfo = fileInfo, Result = result });
        return result;
    }

    public IEnumerable<CompileEntry> CompilationLog
    {
        get
        {
            return _log;
        }
    }

    public class CompileEntry
    {
        public RelativeFileInfo FileInfo { get; set; }
        public CompilationResult Result { get; set; }
    }
}

The easiest way to grab information from the class is to register the class as a singleton during Startup::Configure.

 services.AddSingleton<IRazorCompilationService, RazorCompilationServiceSpy>();

Note that the real RazorCompilationService runs as a transient service in a typical ASP.NET application, but for this simple experiment we are ignoring all the terrible threading problems that might arise using singletons and regular collection classes like a List<T>.

Inside a Razor view we can use the following code to see the compilation results.

@using Microsoft.AspNet.Mvc.Razor.Compilation;

@inject IRazorCompilationService CompilationSpy

@functions {
    public RazorCompilationServiceSpy GetCompilationSpy()
    {
        return (RazorCompilationServiceSpy)CompilationSpy;
    }
}

<section>
    <h3>Compilation Results</h3>

    @foreach (var result in GetCompilationSpy().CompilationLog)
    {
        <h4>@result.FileInfo.RelativePath</h4>
        <pre>@result.Result.CompiledContent</pre>

    }

</section>

Which yields output like the following:

image

Serving Up node_modules In ASP.NET

Tuesday, February 2, 2016 by K. Scott Allen

The wwwroot folder in ASP.NET isn't the only place for static files. Briefly, in haiku form:

Serve files from anywhere

Configure static file middleware

Each provider thaws the frozen bits of winter


Recently, I wanted to serve files from both wwwroot and node_modules, so I used code like the following in the Startup class:

// this will serve up wwwroot
app.UseFileServer();

// this will serve up node_modules
var provider = new PhysicalFileProvider(
    Path.Combine(environemnt.ApplicationBasePath, "node_modules")
);
var options = new FileServerOptions();
options.RequestPath = "/node_modules";            
options.StaticFileOptions.FileProvider = provider;
options.EnableDirectoryBrowsing = true; 
app.UseFileServer(options);

 

Note that the UseFileServer method installs static files, default files, and directory browser middleware with a single method call.

You could also use the same technique to serve files from bower_components. Personally, I've stopped using bower and install all client assets using npm for various reasons (including the simplicity, and also Typescript's ability to find modules in node_modules).

A Different Perspective on ASP.NET Middleware

Monday, February 1, 2016 by K. Scott Allen

When I was a boy, my parents would select a weekend every late summer to freeze corn for our Sunday meals in the winter months. The process started early in the morning when dad would drive us to a local farm. We’d purchase a few hundred ears of un-shucked corn and load the corn into our own laundry baskets to bring them home.

Once home, we’d setup a processing pipeline for the corn. I was first in the pipeline. I’d pick an ear from the basket, shuck off the squeaky green husk, and hand the ear to mom. Mom would gently remove silk from the cob with a soft vegetable brush and not so gently eradicate damaged kernels with a palm-sized paring knife. My mom passed the corn to my dad, who would bundle up a dozen or so ears and drop them into boiling water. After a few minutes of blanching, my dad would transfer the hot corn into an ice bath and then pass the ears back up the pipeline to my mom.

Mom would use a simple device my father made to help cut the corn from the cob. The device was a small hardwood board, about ½ inch think, with a nail through the middle. Pushing the cob onto the nail made for easier cutting with a boning knife, as the cob would stand up without the need to place any fingers in the cutting area. Mom could then sweep the cut kernels off the board and into a bowl where it was my responsibility to measure 2 cups of corn into freezer bags, and keep count of the total number of bags.

Allen Family Middleware For Corn Processing

The corn started with me un-husked and returned to me as whole cut kernels in puddle of sweet, milky juice. Well, not all the corn made the entire trip up and down the family food processing line. If I spotted an obviously bad ear, I always had the option of throwing the ear away instead of passing the ear to mom.

Substitute “HTTP request” for corn and “middleware component” for me, mom, and dad, and you’ll have an idea of how the middleware pipeline works in ASP.NET. Each component has a job to perform when the component receives a request. Each component can perform some work and optionally pass the request to the next component. Each HTTP transaction can visit each piece of middleware once on the way in, and once on the way out.

HTTP Processing Middleware

Now that I’ve made the analogy, it’s hard to look at any Startup.cs and not think about being a boy again in August.

Working With Typed Headers in ASP.NET

Monday, November 30, 2015 by K. Scott Allen

Inside of a controller in ASP.NET 5, the Request and Response properties both give you access to a Headers property. Headers is a simple IHeaderDictionary and will ultimately hand out string values.

Bring in the Microsoft.AspNet.Http namespace and you'll find a GetTypedHeaders extension method available for both Request and Response. Instead of working with raw strings, this extension method allows you to work with classes like MediaTypeHeaderValue, proper numbers, and strong types in general. 

var requestHeaders = Request.GetTypedHeaders();
var responseHeaders = Response.GetTypedHeaders();

var mediaType = requestHeaders.Accept[0].MediaType;
long? length = responseHeaders.ContentLength;

// ...
Pluralsight Courses
What JavaScript Developers Should Know About ECMAScript 2015
The Podcast!