ASP.NET Core 2.0 MVC with ReactJS.NET — Basic Setup and Example Template

I wanted to create a web application with ASP.NET Core, using some JavaScript goodies and I spent a couple of days (and nights) figuring out what to use, how to use it, what (tf) ’s Webpack.

Internet is full with old tutorials and examples, so my digging was a little bit longer than I expected. For that I decided to make a tutorial on how I managed to create an app with the newest versions of technologies I used. Have fun! 🙂

Note: I assume you know what ASP.NET Core, MVC, ReactJS are. I also wouldn’t go through all the steps in detail considering there are tutorials about these things. We go through the new and unexplained stuff. Let’s go!

Blank ASP.NET Core solution with Visual Studio 2017

  1. We start with creating an empty ASP.NET Core Web Application. I will use an empty one because of unnecessary MVC files at the moment. I named my project ASPNETCoreReactNET-Example.

Configure our MVC

Note: Go through the steps even if you’ve created a project with MVC template. There are some changes you should do.

  1. Go to our Startup.cs and change the method ConfigureServices from void to return IServiceProvider. Otherwise we’ll get an exception because of the 2.0 version…
  2. Don’t forget to add MVC!
public IServiceProvider ConfigureServices(IServiceCollection
services)
{
services.AddMvc();
return services.BuildServiceProvider();
}

3. Add code to Configure method.

public void Configure(IApplicationBuilder app, 
IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
    app.UseStaticFiles();
    app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "
{controller=Home}/{action=Index}/{id?}");
}
);
}

4. Add folders — Controllers, Models, Views and files. Lets work with my example project:

Models/UserModel.cs

namespace ASPNETCoreReactNET_Example.Models
{
public class UserModel
{
public string Name { get; set; }
public int Age { get; set; }
}
}

Controllers/HomeController.cs

namespace ASPNETCoreReactNET_Example.Controllers
{
using ASPNETCoreReactNET_Example.Models;
using Microsoft.AspNetCore.Mvc;

public class HomeController : Controller
{
public IActionResult Index()
{
return this.View();
}
       public IActionResult Test()        
{
// Some hardcoded model for test.
var user = new UserModel { Name = "Test User", Age = 18 };
return this.View(user);
}
}
}

Views/Home/Index.csthml

@{    
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<a asp-action="Test">Go to example</a>

Views/Home/Test.cshtml — we’ll add some code a little bit later.

Setup ReactJS.NET

  1. Go to Manage NuGet Packages and install React.AspNet package.
  2. In Startup.cs we should add React, right?

Above AddMvc method, add:

services.AddReact();

In Configure method, above UseStaticFiles, add:

// Initialise ReactJS.NET. Must be before static files.
app.UseReact(config =>
{
// If you want to use server-side rendering of React components,
// add all the necessary JavaScript files here. This includes
// your components as well as all of their dependencies.
// config
// .AddScript("~/Source/Components/ExampleComponent.jsx")
// .AddScript("~/Source/main.js");

// If you use an external build too (for example, Babel,
// Webpack, Browserify or Gulp), you can improve performance by
// disabling ReactJS.NET's version of Babel and loading the
// pre-transpiled scripts.

// This is our set up for ASP.NET Core :) In older versions
// you should initialise in App_Start/ReactConfig.
config
.SetLoadBabel(true)
.AddScriptWithoutTransform("~/dist/bundle.js")
.AddScript("~/Source/Components/ExampleComponent.jsx");
});

Yes, you’re getting some red lights in your method (even if you don’t see them, bruh). Comment everything, we’ll use it later. 🙂

3. Views/_ViewImports.cshtml

Go there and type:

@using React.AspNet

Setup (that evil) Webpack

Webpack and so-called bundles help us to organize our, lets say, front-end files so everything we need to render things the browser should download, reference itself and just use.

Note: My post is getting longer so go down in my list with resources if you want to learn more. (psst, we also don’t want to bother people who already know these things :))

Note: I assume you have installed NodeJS.

  1. We need a package.json file for our project. This file holds metadata and helps npm to install the project’s dependencies. Open the command prompt window, navigate to the path where your .csproj file is and type:
npm init -y

Your package.json should look like this:

{
"name": "ASPNETCoreReactNET-Example",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
},
"keywords": [],
"author": "",
"license": "ISC"
}

2. Webpack is a module, let’s install it!

npm install webpack --save-dev

Now you should have node_modules folder with some modules.

The “ — save-dev” option adds a “dev dependency” to the package.json file, instead of a run-time dependency. This indicates that the Webpack package is only useful during development. That would make sense, as once we have created the “bundles” as we require, we would use them directly in production. The package.json file should look similar to this:
{
"name": "ASPNETCoreReactNET-Example",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^4.6.0"

}
}

3. Create bundle.

Open package.json and add in scripts:

...
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"wbp": "webpack"
...

The wbp we’ll use as an npm command. 🙂 It will create our bundle file, just be patient. We must say the project which is our entry point and our output (bundle) file. For achieving this let’s finally create a webpack.config.js file.

Go in you main project folder and create it. Fill it with this:

const path = require('path');

module.exports = {
// This is our entry point containing the code
// required to perform server-side rendering.
entry: './wwwroot/source/main.js',
output: {
path: path.resolve(__dirname, 'wwwroot/dist'),
filename: 'bundle.js'
},
module: {
// Transform .jsx files.
rules: [
{ test: /\.jsx$/, use: 'jsx-loader?harmony' }
]
},
resolve: {
// Ensure we can deal with .js and .jsx and require files.
extensions: ['.js', '.jsx']
},
// Set mode for development, production or none.
mode: 'none'
};

Note: If you’re using my example this is what you need to write. If not just replace the entry path. You can do this.

Note: In the official ReactJS.NET documentation, the tutorial is for older Webpack version. This is the syntax covered for Webpack 4 and cleaning all the exceptions I discovered. 😉

We also need to install two more packages:

npm install --save-dev expose-loader
npm install --save-dev jsx-loader

Before running the wbp command let’s do the last thing. (You can try of course the npm run wbp but your bundle will not cover the code which we’ll write later so keep going!)

React.NET stuff

  1. Create folder Source.

My Source folder is in the wwwroot. I’m not sure if this is a good practice (it’s not, tho) so you can add it in your project path.

2. Add some JS files in Source folder.

Note: I can’t rely on you that you’ll go bottom of this story and read more. So, with a little bit of this guide I made my js files. If you haven’t used these things I know you’re confused. Just read more and learn.

Let’s see what I have in my example:

Source/main.js

// ReactJS.NET needs to expose components globally, so we do this
var Components = require('expose-loader?Components!./components');

Source/Components/index.js

// Here are all the components for render server-side.
module.exports = {
ExampleComponent: require('./ExampleComponent')
};

JS is not loud and there are no exceptions. How peaceful. Don’t let it deceive you. 😄 We have a lot more work to do.

3. Add a magical JSX file in Source/Components folder.

JSX is a file type used by React which provides syntactic sugar. 🍬

Source/Components/ExampleComponent.jsx

// This is our component.
class ExampleComponent extends React.Component {
render() {
return (
<div className="testDiv">
<h1>{this.props.user.name}</h1>
<h3>{this.props.user.age}</h3>
</div>
);
}
}

4. Good. Remember we comment the whole React middlewear? Go there and uncomment just as I did (yeah, I know we don’t have bundle.js yet).

5. Also we left our Views/Home/Test.cshtml alone and unfinished. Go there and type:

@{
ViewData["Title"] = "Test";
}

<!--First load all scripts required, add our bundle file and render our component.-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react.js"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react- dom.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/remarkable/1.7.1/remarkable.min.js">
</script>
<script src="~/dist/bundle.js"></script>
@Html.React("ExampleComponent", new { user = this.Model})
@Html.ReactInitJavaScript()

6. Now we are ready to open command prompt window (again), go to our project path (again) and type:

npm run wbp

I hope everything goes smoothly. Our bundle should be created. Now you can build your project and see you’ve passed an MVC model to ReactJS which can in our case display it (remember, it’s read only… you can play around to learn more). 🙂

The most important part is we managed to create and setup a simple ASP.NET Core 2 web application with ReactJS.