Dogs Chasing Squirrels

A software development blog

Category Archives: Uncategorized

React and .NET Core WebAPI with F# Part 2: React

0

Following Part 1, we’re going to try to create an application with a pure React frontend and an F#-based WebApi backend.

I’m going to inject a bit of editorializing here: With client-side rendering, server-side rendering including ASP.NET MVC is dead. Why bother mixing cshtml and JavaScript when JavaScript alone will do it? This reduces the server-side code to business logic and data fetching returning JSON. Which further means that on the server we can use whatever technology is best suited to that job and switch it out as necessary. Once the back end is separate from the front end it’s easy enough to switch a C# WebAPI with F# or maybe with Erlang. We can use whatever is most efficient.

The F# Solution

We’re going to break with what we did in Part 1 and start a new F# solution. In Visual Studio, create a new solution called “ReactWebApiDemo” and under that a new F# WebAPI project called, again, “ReactWebApiDemo”. It will create a blank project with a controller called ValuesController.

If you run the application it will open with a blank screen. You can navigate to the API to see it return some JSON, e.g. http://localhost:54111/api/values

Enabling static web content

We want the WebApi side producing JSON while our main site runs on static HTML and JavaScript. The project should have a folder called “wwwroot”. This is where our static pages go. Start by putting an “index.html” in that folder, e.g.

<html>
<head>
    <meta charset="utf-8">
    <title>Test</title>
</head>
<body>
    <h1>Test</h1>
</body>
</html>

Now if you run the solution and load the root URL, e.g. “http://localhost:54111/&#8221;, what do you see? The answer: nothing. We have to both enable static files (to get it to read from the folder) and default paths (to get it to recognize that / should load /index.html). To so this, modify Startup.fs and add change the Configure method to do this:

    member this.Configure(app: IApplicationBuilder, env: IHostingEnvironment) =
        app
            .UseDefaultFiles()
            .UseStaticFiles()
            .UseMvc() |> ignore

Adding our TypeScript, Less, React, etc. back in

If you have the files from part 1, copy
* .babelrc
* package.json
* package-lock.json
* tsconfig.json
* webpack.config.json
into the project folder and run

npm install

This will restore the modules.

Our files are going to wwwroot now, so first let’s establish this layout:
* wwwroot/
* wwwroot/components – Our React components
* wwwroot/css – Our CSS files
* wwwroot/js – Our scripts
* wwwroot/dist – Our bundled output

We need to change webpack.config.js with the entry and the output:

    // Entry: a.k.a. "Entry Point", the JS file that will used to build the JavaScript dependency graph
    // If not specified, src/index.js is the default.
    entry: "./wwwroot/js/index.js",
    // Output: Where we'll output the build files.
    output: {
        // Path: The directory to which we'll write transformed files
        path: path.resolve(__dirname, 'wwwroot/dist'),
        // Filename: The name to which we'll write our bundled JavaScript.
        // If not specified, dist/main.js is the default.
        filename: 'main.js'
    },

Running webpack on build

One more thing we can do is make webpack run automatically every time we do a build. Edit your .fsproj file and add the following:

<br />    <Target Name="WebpackDebug" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug'">
        <Message Importance="high" Text="Performing webpack build (Debug)..." />
        <Exec Command="npm run debug" />
    </Target>

    <Target Name="WebpackRelease" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Release'">
        <Message Importance="high" Text="Performing webpack build (Release)..." />
        <Exec Command="npm run release" />
    </Target>

Stopping Visual Studio TypeScript compilation

By default, Visual Studio is going to try to compile our typescript and put it in its own “dist” folder. We’re using webpack so we don’t need it. To disable it, edit .fsproj and add:

    <PropertyGroup>
        <TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
    </PropertyGroup>

Building and Running

Let’s put some code in input.js and run the project to make sure it works.

import style from '../css/site.less'

function test() {
    console.log("test");
}

window.onload = test;

Now we run it from Visual Studio, the browser opens, and we get… a page with script and style errors.

Content Security Policy

Here we’re going to run into a little problem with webpack and the application’s Content Security Polity. Using webpack’s “import style from ‘blah.css'” is an unsafe style import. Firefox or Chrome will show you a message like “The page’s settings blocked the loading of a resource at self (“style-src”).” and they’re right. A default Content Security Policy defines where you can load scripts and styles from and the default is “script-src ‘self’; style-src ‘self’;”. If we want to load CSS like this we need to override the security policy in .NET Core. I don’t actually recommend this, but until I find a better way, you can modify the Configure method like so:

    member this.Configure(app: IApplicationBuilder, env: IHostingEnvironment) =
        let staticFileOptions = StaticFileOptions()
        staticFileOptions.OnPrepareResponse <- fun ( context ) ->
            context.Context.Response.Headers.Add(
                        "Content-Security-Policy",
                        StringValues(
                            "script-src 'self'; " +
                            "style-src 'self' 'unsafe-inline'; " +
                            //"style-src 'self'; " +
                            "img-src 'self'" 
                        ) );
        app
            .UseDefaultFiles()
            .UseStaticFiles( staticFileOptions )
            .UseMvc() 
            |> ignore

This applies the content security policy to static files. To apply it to all files, use:

        app
            .UseDefaultFiles()
            .UseStaticFiles()
            .UseMvc() 
            .Use( fun ( context : HttpContext ) ( next : Func<Task> ) ->
                async {
                    context.Response.Headers.Add(
                        "Content-Security-Policy",
                        StringValues(
                            "script-src 'self'; " +
                            "style-src 'self' 'unsafe-inline'; " +
                            //"style-src 'self'; " +
                            "img-src 'self'" 
                        ) );
                    return! next.Invoke() |> Async.AwaitTask
                } |> Async.StartAsTask :> Task
            )
            |> ignore

At the time of writing this, webpack has the beginning of the concept of adding a nonce but they don’t seem to be doing it right in that it appears to be a static value rather than a per-request value making the application less secure.

Now with that temporarily solved…

React Router

We’re going to use react-router for page navigation. Add it with npm.

npm install react-router react-router-dom
  • react-router – The core react-router library.
  • react-router-dom – The DOM bindings (as opposed to React Native)
    And for TypeScript compatibility:
npm install @types/react-router @types/react-router-dom
  • @types/react-router – TypeScript types for react-router
  • @types/react-router-dom – TypeScript types for react-router-dom

Let’s follow react-router’s basic example. Create a file called “App.jsx” and add the following code (taken verbatim from the given link):

import React from 'react'
import {
    BrowserRouter as Router,
    Route,
    Link
} from 'react-router-dom'

const Home = () => (
    <div>
        <h2>Home</h2>
    </div>
);

const About = () => (
    <div>
        <h2>About</h2>
    </div>
);

const Topic = ({ match }) => (
    <div>
        <h3>{match.params.topicId}</h3>
    </div>
);

const Topics = ({ match }) => (
    <div>
        <h2>Topics</h2>
        <ul>
            <li>

                    Rendering with React

            </li>
            <li>

                    Components

            </li>
            <li>

                    Props v. State

            </li>
        </ul>


         (
            <h3>Please select a topic.</h3>
        )} />
    </div>
);

const BasicExample = () => (

        <div>
            <ul>
                <li>Home</li>
                <li>About</li>
                <li>Topics</li>
            </ul>

            <hr />




        </div>

);

export default BasicExample

Now change index.js to render our React routes:

import style from '../css/site.less'
import React from 'react'
import ReactDOM from 'react-dom'
import BasicExample from './App'

function test() {
    console.log("test");
    ReactDOM.render(BasicExample(), document.getElementById('root'));
}

window.onload = test;

Since we're rendering in the element "root" we need to define that in index.html:

<br />    <div id="root">
        <h1>Test</h1>       
    </div>

Run the page and you should see the example in action.

URL handling

Note that react-router will update the URL as you click on the various links. But you'll also notice that if you bookmark one of the links, e.g. "/about" and try to go back to it, it'll fail.
What we need to do is route all our URLs to the React page. We can do this with a URL rewrite rule in web.config:

<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />

Basically, everything that isn’t /api will get routed back to the React controller. This isn’t actually ideal – it also redirects scripts and images. We have a couple of options:
* We can ensure all our router paths have some distinct prefix and route only those. Imagine we put all our route paths under /r/ then we could do: (note "^" means "start of the path").
* We could exclude other paths, like /images, the same way we exclude /api. e.g.
.

Using TSX instead of JSX

If we want to use TypeScript instead of JavaScript we need to convert App.jsx to App.tsx. The converted example looks like this:

import * as React from 'react'
import * as ReactRouter from 'react-router'
import {
    BrowserRouter as Router,
    Route,
    Link

} from 'react-router-dom'

const Home = () => (
    <div>
        <h2>Home TS</h2>
    </div>
);

const About = () => (
    <div>
        <h2>About TS</h2>
    </div>
);

const Topic = ({ match } : { match: ReactRouter.match } ) => (
    <div>
        <h3>{match.params.topicId}</h3>
    </div>
);

const Topics = ({ match }: { match: ReactRouter.match }) => (
    <div>
        <h2>Topics</h2>
        <ul>
            <li>

                    Rendering with React

            </li>
            <li>

                    Components

            </li>
            <li>

                    Props v. State

            </li>
        </ul>


         (
            <h3>Please select a topic.</h3>
        )} />
    </div>
);

const BasicExample = () => (

        <div>
            <ul>
                <li>Home TS</li>
                <li>About TS</li>
                <li>Topics TS</li>
            </ul>

            <hr />




        </div>

);

export default BasicExample

The main change is to convert untyped parameters like Topic = ({ match }) to typed parameters like Topic = ({ match } : { match: ReactRouter.match } ) where match<P> is a type found in @types/react-router.

Fetching data from the API

If you created the default F# project, you will already have a ValuesController that supports a Get returning an array:

[<Route("api/[controller]")>]
type ValuesController () =
    inherit Controller()

    [<HttpGet>]
    member this.Get() =
        [|"value1"; "value2"; "value A"; "value B"|]

The usual way, I’m told, for a React component to load values via AJAX is in componentDidMount. Let’s change our topics to fetch data from the API. It can’t be an arrow function anymore.

class Topics extends React.Component<any, { values: any[] }>{
    constructor(props: any) {
        super(props);
        console.log("Topics.ctor");
        this.state = { values: [] };
    }
    public componentDidMount() {
        console.log("componentDidMount");
        fetch("/api/values")
            .then((response) => {
                console.log(" got response " + response);
                return response.json();
            })
            .then((json) => {
                console.log("got json " + json);
                this.setState({ values: json });
            })
            ;

    }
    public render() {
        if (null === this.state) return null;
        return <div>
            <h2>Topics</h2>
            <ul>
                {this.state.values.map(function (value: any, index: number) {
                    return <li>{value}</li>;
                })}
            </ul>
        </div>
            ;
    }
}

And that’s it. When we load the /topic URL we’ll see the list from our API.

VBA for Engineers

0

I make oil and gas software and work with engineers a lot. I am one myself, by education. Engineers like to use Excel and if they remember the little programming they took in university, they like to extend what Excel can do by using Visual Basic for Applications, or VBA. VBA is terrible. It’s based on VB6 which is also terrible. Together, VB6, VBA, and VB.Net make up three of the top five most dreaded languages in the most recent Stack Overflow Developer Survey.

The saying goes that when the only tool you have is a hammer, every problem looks like a nail. Engineers’ tool is VBA so you find them using it where it’s not appropriate or useful. Moreover, they’re amateur programmers so to a professional software developer like me, opening up a macro-enabled Excel file is like a carpenter walking up to a woodworking project and seeing a screw that’s been pounded double surrounded by a bunch of circular indentations.

They still ask me for help with their Visual Basic problems and rather than turn them away I’ve finally said that I’m glad to help. After all, the first step in getting help with a VBA problem is admitting you have a VBA problem. To that end, I’ve tried to establish a 12-step program based on the traditional 12-step programs like AA. VBAA, if you will.

AA VBAA
We admitted we were powerless over alcohol—that our lives had become unmanageable. We admitted we were powerless over VBA—that our Excel-based workflow had become unmanageable.
Came to believe that a Power greater than ourselves could restore us to sanity. Came to believe that a department greater than ourselves could restore us to sanity.
Made a decision to turn our will and our lives over to the care of God as we understood Him. Made a decision to turn our will and our lives over to the care of IT as we understood them.
Made a searching and fearless moral inventory of ourselves. Made a searching and fearless moral inventory of our Excel-based workflow.
Admitted to God, to ourselves, and to another human being the exact nature of our wrongs. Admitted to IT, to ourselves, and to another human being the exact nature of our wrongs.
Were entirely ready to have God remove all these defects of character. Were entirely ready to have IT remove all these defects of character.
Humbly asked Him to remove our shortcomings. Humbly asked IT to remove our VBA macros and modules.
Made a list of all persons we had harmed, and became willing to make amends to them all. Made a list of all persons we had harmed, and became willing to make amends to them all.
Made direct amends to such people wherever possible, except when to do so would injure them or others. Made direct amends to such people wherever possible, except when to do so would injure them or others.
Continued to take personal inventory, and when we were wrong, promptly admitted it. Continued to take personal inventory, and when we were wrong, promptly admitted it.
Sought through prayer and meditation to improve our conscious contact with God as we understood Him, praying only for knowledge of His will for us and the power to carry that out. Sought through prayer and meditation to improve our conscious contact with IT, praying only for knowledge of better programming languages for us and the power to carry that out.
Having had a spiritual awakening as the result of these steps, we tried to carry this message to alcoholics, and to practice these principles in all our affairs. Having had a spiritual awakening as the result of these steps, we tried to carry this message to other Engineers, and to practice these principles in all our affairs.

I encourage all engineers suffering from a VBA problem to seek a sponsor in their IT’s software development department.

Akka.NET and Unity IoC

0

Even though Akka.NET supposedly supports dependency injection through its DI libraries (e.g. Akka.DI.Unity), it’s not very good. In the documentation you’ll see examples like:

Context.DI().Props<MyActor>()

That Props call doesn’t take any arguments so there’s no way to actually inject parameters into the call. Let’s say we have this actor:

public class MyActor : ReceiveActor {
  public MyActor( string a, IFoo b, IBar c ) {
    // ...
  }
}

Further say we want to specify a but let Unity resolve IFoo and IBar from configuration. If we were just creating the object normally we would write:

var myActor = UnityContainer.Resolve<MyActor>( 
  new ParameterOverride( "a", "ABC" ) 
  );

But that’s not how we create actors. We create actors using ActorOf and specify Props. We do this so that Akka.Net can recreate the actors if they fail.

If we were to create the actor normally without dependency injection we would write something like:

var myActorRef = actorRefFactory.ActorOf( 
  Props.Create( () => new MyActor( "ABC", ??, ?? ) 
  );

If we do that, we aren’t getting our interfaces from Unity.

So let’s try dependency injection. If we were to use Akka.DI.Unity we would have:

var myActorRef = actorRefFactory.ActorOf(
  Context.DI.Props<MyActor>() 
  );

But then there’s no way to specify our parameter.
We’re stuck. We can specify all parameters or none but can’t specify some and let unity take care of the others like we usually want.

Here’s a way you can do it that doesn’t involve the Akka.DI libraries:

IIndirectActorProducer

It turns out that Props is not the only way to create an actor. If you dive into the source code, you can see that there’s a IIndirectActorProducer class that will create an actor without Props by implementing a Produce method.
Here’s an implementation that takes a IUnityContainer and the ResolverOverrides in its constructor and uses them to create the actor when called:

    /// <summary>
    /// A <see cref="IIndirectActorProducer" /> that uses a <see cref="IUnityContainer" /> to resolve instances.
    /// </summary>
    /// <remarks>
    /// This is only used directly by the <see cref="UnityActorRefFactory"/>
    /// </remarks>
    /// <typeparam name="TActor"></typeparam>
    internal sealed class UnityActorProducer<TActor> : IIndirectActorProducer where TActor : ActorBase {

        /// <summary>
        /// The resolver overrides.
        /// </summary>
        private readonly ResolverOverride[] _resolverOverrides;
        /// <summary>
        /// The unity container.
        /// </summary>
        private readonly IUnityContainer _unityContainer;

        /// <summary>
        /// The constructor.
        /// </summary>
        /// <param name="unityContainer">The unity container.</param>
        /// <param name="resolverOverrides">The resolver overrides.</param>
        public UnityActorProducer( IUnityContainer unityContainer, params ResolverOverride[] resolverOverrides ) {
            this._unityContainer = unityContainer.CreateChildContainer();
            this._resolverOverrides = resolverOverrides;
        }

        /// <summary>
        /// See <see cref="IIndirectActorProducer.ActorType"/>
        /// </summary>
        public Type ActorType => typeof( TActor );

        /// <summary>
        /// See <see cref="IIndirectActorProducer.Produce" />
        /// </summary>
        /// <returns></returns>
        public ActorBase Produce() {
            // Create the actor using our overrides
            return this._unityContainer.Resolve<TActor>( this._resolverOverrides );
        }

        /// <summary>
        /// SEe <see cref="IIndirectActorProducer.Release" />
        /// </summary>
        /// <param name="actor"></param>
        public void Release( ActorBase actor ) {
            // Do nothing
        }

    }

We can create Props using the producer like this:

        /// <summary>
        /// Creates <see cref="Akka.Actor.Props" /> using the <see cref="IUnityContainer" /> and any <see cref="ResolverOverride" />s provided.
        /// </summary>
        /// <typeparam name="TActor"></typeparam>
        /// <param name="unityContainer"></param>
        /// <param name="resolverOverrides"></param>
        /// <returns></returns>
        public Props Props<TActor>( IUnityContainer unityContainer, params ResolverOverride[] resolverOverrides ) where TActor : ActorBase {
            // Use a UnityActorProducer to create the object using the container and resolver overrides.
            return Akka.Actor.Props.CreateBy<UnityActorProducer<TActor>>( 
                unityContainer, 
                resolverOverrides 
                );
        }

So creating our actor would look like this:

var myActorRef = Context.ActorOf(
  Props<MyActor>( 
    unityContainer, 
    new ParameterOverride( "a", "ABC" ) 
  )
  );

It uses our resolver overrides for the first parameter and the unity configuration for our additional parameters, just as we want.

Book recommendation: Seven Languages in Seven Weeks

0

I haven’t posted anything in a while (I’m intermittently working on converting the Replicon Add-In to F#), so I’ll throw up this book recommendation for Seven Languages in Seven Weeks by Bruce Tate.

The languages are:
1. Ruby – A well known and interesting object-oriented scripting language.
2. Io – A language based on prototyping.
3. Prolog – A logic-based language. I saw this one back in university.
4. Scala – A hybrid O-O/functional language.
5. Erlang – The functional language made in the 80s for telephone switches that is the hot new thing because of how well it handles concurrency and load, a problem we face in all modern web applications.
6. Clojure – A lisp implementation on Java
7. Haskell – A purely functional language.

And if you aren’t already using it, I recommend using Chocolatey, the apt-get style package manager for Windows, to download these programming languages to play around with. Using Chocolatey is a whole lot easier than hunting down all the installers you’d need otherwise.

Fault-safe WCF Proxy Generator

0

In WCF, clients connect to servers using channels that implement a particular service contract interface.  This ordinarily works very well – until something throws an exception.  Let’s say you’re a client, you have some channel object you can cast as IWhatever and you can make calls on its methods.


this._factory = new ChannelFactory<IMathContract>( endpoint );

this._channel = this._factory.CreateChannel();

int c = this._channel.Add( a, b );

If one of those methods throws an error, the channel will become faulted and every subsequent call will throw an exception like “The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.”.  What you have to do now is abort and recreate the channel.  But this error could happen anywhere.  So what we usually do is build a proxy.  The proxy wraps the channel, implementing all the interface’s methods, and aborts the channel if any of these calls throw an exception.


 public int Add( int a, int b ) {
    try {
         return this.GetChannel().Add( a, b );
     } catch ( Exception ) {
         this.Abort();
         throw;
     }
 }

Writing these proxies is tedious, so I’ve created a utility that uses IL generation to dynamically generate a proxy given a service contract.


IMathContract channel = FaultSafeProxyEmitter<IMathContract>.Create( "MockEndpoint" );

This creates a fault-tolerant channel that will abort and reset if an exception is thrown.  The channel will never remain in the Faulted state.  The channel also implements IDisposable to properly close the underlying channel when complete.

The code is up on github.