Click here to Skip to main content
15,608,989 members
Articles / .NET
Technical Blog
Posted 22 Aug 2017

Tagged as


6 bookmarked

NodeServices: Where Javascript and .NET Meet Back on the Other Side

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
22 Aug 2017CPOL5 min read
NodeServices: Where Javascript and .NET Meet Back on the Other Side

NodeServices: Where Javascript and .NET Meet Back on the Other Side

JavaScript is everywhere. It's in the browser, on the server, and it's climbing through your windows and snatching your people up. And because it's a fairly trivial language to pick up (but impossible to master), it can be extremely useful when you want to do something on the server.

This was and still is the real appeal of technologies like Node.js, however it's quite easy to do within the realm of .NET. This post is going to provide a very basic overview of how to target and execute some arbitrary JavaScript code within .NET without ever touching the browser.

What is/are NodeServices?

I'll let the creator, Steve Sanderson, explain it as follows:

  • NodeServices provides a fast and robust way for .NET code to run JavaScript on the server inside a Node.js environment. You can use this to consume arbitrary functionality from NPM packages at runtime in your ASP.NET Core app.

  • Most applications developers don't need to use this directly, but you can do so if you want to implement your own functionality that involves calling Node.js code from .NET at runtime.

You can find the project itself on GitHub as well, which goes far beyond just interacting with just Node in .NET.

Setting Up NodeServices

This particular example of NodeServices depends on .NET Core 2.0, which you will want to install from here if you want to follow along. The steps may work with earlier versions, but if you run into issues, consider trying 2.0.

In this example, we will build a simple Web API that will rely on NodeServices to perform some operations. So to get started, we'll first need to create a new project:

dotnet new webapi  

If you aren't a command line person, Visual Studio 2017 Update 3 should have the necessary tools to create .NET Core 2.0 applications through the traditional GUI.

Configuring NodeServices

Getting started with NodeServices is dead simple. You basically just need to include the Microsoft.AspNetCore.NodeServices NuGet package within your application via the following command:

dotnet add package Microsoft.AspNetCore.NodeServices  

You should then see it within your project definition as well:

    <!-- Others omitted for brevity -->
    <PackageReference Include="Microsoft.AspNetCore.NodeServices" Version="2.0.0" />

Then, you'll need to configure the necessary middleware to handle using the service within your application in the ConfigureServices() method of your Startup.cs file:

public void ConfigureServices(IServiceCollection services)  
    // This will configure the NodeServices service

After configuring the services, you'll now be able to use dependency-injection to handle injecting this into your application at the controller level:

public class ValuesController : Controller  
        private readonly INodeServices _nodeServices;

        public ExampleController(INodeServices nodeServices)
            _nodeServices = nodeServices;

        // Other actions here

Or at a single method/action level with the [FromServices] attribute:

public async Task<IActionResult> Example([FromServices] INodeServices nodeServices)  
       // TODO: Cool stuff

Now that we have the actual Node Services wired up, let's look at what has to be done on the JavaScript side of things get the two sides to play nicely with one another.

Actually Using NodeServices

Since we are going to be calling JavaScript code from within .NET, we will first need to define the actual code that we want to call. So to get started, we will create a new Scripts folder at the root of the current project and a new file called Add.js within it:

NodeServices: Where Javascript and .NET Meet Back on the Other Side

This Add.js file is going to function as a single module that will export a function which will be called by our C# code. For the sake of simplicity, we will start by simply adding two numbers together and returning the result via a callback:

module.exports = function(a, b, callback) {  
  let result = a + b;

Jumping back to the .NET side of things, we can configure our service to point to our new JavaScript file using the InvokeAsync<T>() method, which expects the path to the file being invoked and a type to indicate the expected return type:

public async Task<long> Add(int x = 11, int y = 31)  
    return await _nodeServices.InvokeAsync<long>("Scripts/Add.js", x, y);

After running your application and hitting that endpoint, you'll quickly see the expected result and that no client-side JavaScript was harmed during the creation of the response:

NodeServices: Where Javascript and .NET Meet Back on the Other Side

Now, if you are familiar with JavaScript, then you know that it can do all sorts of crazy things, especially when you use really dangerous functions like eval(). We'll create another file called Eval.js to add to our existing Scripts folder that looks like this:

module.exports = function (callback, x) {  
    let result = eval(x);
    callback(null, result);

For demonstration purposes, let's create another method that accepts some arbitrary text and evaluates it within our Web API controller:

public async Task<string> Eval(string expression = "6 * 7")  
    return await _nodeServices.InvokeAsync<string>("Scripts/Eval.js", expression);

We can see this in action below:

NodeServices: Where Javascript and .NET Meet Back on the Other Side

NodeServices really shines in scenarios where you might not be able to find the perfect NuGet package that you are looking for, but one exists on npm or somewhere else in the vast JavaScript ecosystem. Simply grab the code that you need, or pull down the actual npm package itself (along with its required dependencies) and use it just as you would expect.

Let's see how something like that might work if we decide to use a fancy npm package to generate QR codes using a bit of text. First, we'll need to install the appropriate npm package:

npm install qr-image  

Again - if you aren't a command line fan, you can download it directly from the source on GitHub or using some other package manager of your choice.

Once you have the QR package downloaded, you can create a new file within your Scripts folder called QR.js. Since we are now in a Node world, you'll just need to wire up the appropriate dependencies via a require() statement that points to your package and add the following code:

let qr = require('./qr-image');  
module.exports = function (callback, text) {  
    var result = qr.imageSync(text, { type: 'png' });

    var data = [];
    result.forEach(i => {

    callback(null, data);

This does the following:

  • Wires up our QR package for use.
  • Uses the string data passed in to generate a QR code image.
  • Reads the image data into a byte[] that our C# code will consume.

At this point, we can write the corresponding method with our API:

public async Task<IActionResult> QR(string text = "42")  
    var data = await _nodeServices.InvokeAsync<byte[]>("Scripts/QR.js", text);
    return File(data, "image/png");

And when we hit that method, we see that the values return as expected:

NodeServices: Where Javascript and .NET Meet Back on the Other Side

This is really just the tip of the iceberg, but it demonstrates just how easy it is to integrate the entire Node ecosystem within .NET to build all sorts of applications.

Give It a Shot!

As mentioned earlier in the post, the npm and Node ecosystems are huge and there are tons of useful packages that you can now pull down and integrate into your ASP.NET applications with ease.

If you don't want to walk through all of these steps by hand, feel free to pull down the code from this demo or check out Steve Sanderson's additional examples found on the NodeServices repo as well:


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Written By
Software Developer (Senior)
United States United States
An experienced Software Developer and Graphic Designer with an extensive knowledge of object-oriented programming, software architecture, design methodologies and database design principles. Specializing in Microsoft Technologies and focused on leveraging a strong technical background and a creative skill-set to create meaningful and successful applications.

Well versed in all aspects of the software development life-cycle and passionate about embracing emerging development technologies and standards, building intuitive interfaces and providing clean, maintainable solutions for even the most complex of problems.

Comments and Discussions

-- There are no messages in this forum --