Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / Node.js

Integrating Vue.js V4 in ASP.NET Core 3.1 MVC & File Uploading using Dropzone

4.91/5 (10 votes)
15 Feb 2020CPOL10 min read 31.7K   689  
Configuration Vue.js v4 in ASP.NET Core 3.1 MVC. Introduction of Node.js, NPM, WebPack and DropZone. Use of Task Runner of NPM and WebPack for compile and bundle.
The topics covered in this article include introduction & installation of Node.js, NPM, WebPack, Vue.js and .NET Core 3.1; how to run/build instruction using NPM and WebPack Task Runner; how to setup Vue.js with ASP.NET Core 3.1 MVC; and configure DropZone with Vue.js and ASP.NET Core 3.1 MVC.

Introduction

We’re used to transferring a file through the browser on the website from the user’s computer/system to a different server. This process is known as file uploading. We know that in the Single-Page-Application, the entire page is loaded in the browser during the initial request and later on, it can update the particular part of the section/page which is changed. That’s how we don’t need to reload the entire page for each update. Anyway, to accomplish the file uploading, we can divide it into two parts. The front-end/UI part of the file upload will be handled using Vue.js and the logical file saving part/back-end will be handled using ASP.NET Core 3.1 MVC. The single file will be buffered in memory using IFormFile and the file content will be accessible as the stream.

Coverage Topics

  1. Introduction & installation of Node.js and NPM
  2. Introduction & installation of Vue.js V4
  3. Introduction & installation of VS 2019 for Dot NET Core 3.1
  4. Introduction & run instruction of NPM and WebPack Task Runner
  5. Integrating/configuring Vue.js with ASP.NET Core 3.1 MVC
  6. Configuration/setup DropZone with Vue.js and ASP.NET Core MVC

Prerequisites

  • Visual Studio 2019 for the .NET Core 3.1
  • Install Node.js, NPM and Vue.js
  • WebPack Task Runner to compile the JS files visually
  • NPM Task Runner to install/update the packages visually

Don't you like study but love to learn? Okay! There're questions for you!

  • Why do you choose Vue.js? - Do you have the option to choose the JS framework (say, Angular/React/Vue.js, etc.)? If yes, then which one should be good for you and why? OR don't you have the option to choose and your team already chose a JS framework (say, Vue.js) for you? If so, then why do they choose it, as there're alternative?
  • Why do you choose NPM? - You have the option to choose like Bower, Yarn or NPM, then why do you choose NPM?
  • Why do you choose WebPack? - You have the option to choose like Grunt, Gulp or WebPack, then why do you choose WebPack?

Introduction of Node.js

  • Node.js is open source command line tool. It uses the Google V8 JavaScript engine to execute the code.
  • Installation of Node.js/NPM - To download Node.js, click on the link (https://nodejs.org/en/download/)
  • Why do you need Node.js/NPM - In a short, you may need to install 3rd party packages in your application. NPM is the command-line utility which help you to install the required packages. But without Node.js, you can't install NPM. You will be asked to install NPM with Node.js installation setup. So, install Node.js to run NPM.

Have You Already Installed Node.js/NPM?

Open the command-prompt, type: node -v and press Enter. If you get the version number, that means you already have it on your machine.

  • To check the npm version, use the following command: npm -v
  • To upgrade the npm version, use the following command: npm i -g npm

Node/NPM Version Related Common Error

Suppose you have the older version in your system and you have upgraded to the latest version. Now if you get any error (like, "TypeError: log.gauge.isEnabled") during the version check using the following command: npm -v, then this is the npm package dependency issue. Remove all of the directories/files from the following path and re-install/repair the Node.js again:

  • C:\Users\[User-Name]\AppData\Roaming\npm-cache
  • C:\Users\[User-Name]\AppData\Roaming\npm

Introduction of Vue.js

Vue.js is a JavaScript framework for single-page-application (SPA) development. This one is similar to the Angular, React.js or Knockout and avoids page reload. Each of these has a different focus and you will have to decide which one is good for you according to your situation. If you have to play with dynamic DOM manipulation, then React.js is good. If you need data-driven CRUD operations, then Angular is good. The position of Vue.Js is in between these situations; but still it likes to deal with dynamic DOM manipulation. However, this is my personal opinion!

Installation of Vue.js V4

Use the following command to install the new version globally: npm install -g @vue/cli.
Why do you need to uninstall the previous version of vue-cli? - If you already installed the vue-cli package (version: 1.0/2.0) globally and want to use new v4, then you have to uninstall the previous version. New version v4 is changed to @vue/cli from vue-cli.

  • To check the version, use the following command: vue --version
  • To uninstall it globally with NPM, use the command: npm uninstall vue-cli -g
  • To install it globally with NPM, use the command: npm install -g @vue/cli

Introduction of Dot NET Core

I don't need to introduce the Dot NET Framework. But if you’ve targeted to run your application on multiple platform like Windows, Mac and/or Linux, then Dot NET Core is perfect because it focuses on the micro-services. Another consideration, if you need docker-containers, then you know that containers is light weight compared to virtual machine (VM).

Installation of Visual Studio 2019

Introduction of WebPack/NPM Task Runner Explorer

Web-pack Task Runner Explorer is used to compile and bundle the JS files; whereas NPM Task Runner Explorer is used to install/update the dependencies packages.

Download and Run Instruction of NPM/WebPack Task Runner for VS 2019

Why Do You Need NPM Task Runner?

This is required when you want to install/update 3rd party packages in the application manually. The “package.json” file is used to save the packages list and working with the Node.js and NPM. In this file, you may add the dependencies where the package name and version look like the following way:
devDependencies”: {“PackageName”: “VersionNumber”}

Image 1

How Web-Pack Works

Let's see the following situation:

  • End-User: Eva, I like your T-Shirt. Where did you get this? I want to buy one.
  • Eva.js: John gifted me this one.
  • End-User: Okay, talk to John and ask him where he got it.
  • Eva.js: Hey John, last Christmas, from where did you buy the T-Shirt that you gave me?
  • John.js: I have bought it from ABC store at IN.

So, the end-user sends one more Http-requests to get the expected result. It means, there is a dependency graph where Eva.js calls John.js. Now if you want to merge both of these JS files into one bundle, then a single http-request is okay to find the file. So, you need the Web-Pack to make those bundles. You can concat, minify and/or uglify your JS files using the Web-Pack. (Concatenation is appending all of the files into one large file; Minification is removing unnecessary whitespace and character without changing the functionality; Uglification is converting the code in such a format that it will be difficult to understand.)

Why Do You Need Web-Pack Task Runner?

In short, considering the above situation, we can say that you need the Web-Pack Task Runner to compile and bundle the JS files.

Image 2

The "webpack.config.js" file pulls all of the configuration and it has an entry point to bring all of the JS files configuration where the bundler starts, then it uses output to get the path and file name configuration to generate the bundle.

JavaScript
module.exports = { 
entry: { app: './wwwroot/js/app.js' }, 
output: { 
publicPath: "/dest/js/", 
path: path.join(__dirname, '/wwwroot/dest/js/'), 
filename: '[name].bundle.js'
 }
} 

Integrating Vue.JS with ASP.NET Core MVC Web Application

Project Creation

Assuming that you can create a new project “ASP.NET Core Web Application>Web Application (Model-View-Controller)”. Now if you don’t want to use the default jQuery library, then you can remove the files and folder from the “wwwroot>lib”. However, this is optional.

Image 3

Template Design

You can modify the default site.css and site.js file according to your requirement.

Image 4

Adding Bootstrap into the App.js File of the Project

Within the “wwwroot/css” directory, I add the app.css file for the CSS and within the “wwwroot/js“ directory, I add the app.js file and to register the “Bootstrap” plugin to use material icons and end up with following:

JavaScript
import $ from 'jquery';
//// Import the Bootstrap Material Design Theme
import 'bootstrap-material-design/dist/css/bootstrap-material-design.min.css';
import 'bootstrap-material-design/dist/js/bootstrap-material-design.min.js';
import 'material-design-colors/dist/material-design.min.css';

//// Import the App Styles
import '../css/app.css';

//// Initialize the Material Design elements when the page loads
$(document).ready(function () {
    $('body').bootstrapMaterialDesign
    $('[data-toggle="popover"]').popover

Note: I add this file just for an example. In this project, I avoid the design/material-icon and focus on the configuration.

Adding NPM Packages into the package.json

You may need Vue, babel, WebPack, bootstrap, etc. packages. Babel is a JavaScript transpiler that compiles and converts old ES5 JavaScript to make browser compatible. All of the packages are saved into the “package.json” file. Now you can install/update these packages using Package-Manager-Console or Task Runner Explorer. For an example, I add some packages and end up with the following:

JavaScript
{
  "name": "HR.App.Web",
  "version": "1.1.1",
  "private": true,
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.5",
    "babel-preset-env": "^1.7.0",
    "babel-preset-es2017": "^6.24.1",
    "bootstrap": "^4.1.3",
    "bootstrap-material-design": "^4.1.1",
    "css-loader": "^1.0.0",
    "fuse.js": "^3.2.1",
    "jquery": "^3.3.1",
    "material-design-colors": "^1.0.2",
    "style-loader": "^0.19.0",
    "uglifyjs-webpack-plugin": "^1.3.0",
    "url-loader": "^0.6.2",
    "vue": "^2.6.10",
    "vue-loader": "^15.4.2",
    "vue-template-compiler": "^2.5.17",
    "webpack": "^4.20.2",
    "webpack-cli": "^3.1.1",
    "webpack-dev-server": "^3.1.9"
  },
  "dependencies": {}
}

If you want to install/update the packages from the package.json file using NPM Task Runner Explorer, then make sure you install the NPM Task Runner Explorer. If you don’t see the Task Runner Explorer, then select the Package.json and click on the right button of the mouse. Now from the Task Runner Explorer, select the install from the package.json and click on the right button of the mouse as shown in the below image. As a result, all of the packages will be installed.

Image 5

The WebPack Configuration and Bundle the js Files

The Web-Pack Task Runner automatically triggers when it finds webpack.config.js file. The file ends up with the following:

JavaScript
"use strict";
const { VueLoaderPlugin } = require('vue-loader');
const path = require('path');
const webpack = require('webpack');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
    entry: {
        app: './wwwroot/js/app.js',
        home: './Views/Home/Index.cshtml.js',
        errorDetail: './Views/Home/ErrorDetail.cshtml.js'
           },
    plugins: [
        new webpack.ProvidePlugin({
            '$': 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery',
            Popper: ['popper.js', 'default']
        }),
        new VueLoaderPlugin()
    ],

    optimization: {
        minimizer: [
            new UglifyJsPlugin({
                cache: true,
                parallel: true,
                uglifyOptions: {
                    compress: false,
                    ecma: 6,
                    mangle: true
                },
                sourceMap: true
            })
        ]
    },
    output: {
        publicPath: "/dest/js/",
        path: path.join(__dirname, '/wwwroot/dest/js/'),
        filename: '[name].bundle.js'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /(node_modules)/,
                query: {
                    presets: ['es2017']
                }
            },
            {
                test: /\.css$/,
                loaders: ['style-loader', 'css-loader']
            },
            {
                test: /\.(png|jpg|gif)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        limit: 8192
                    }
                }
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            }
        ]
    },
    resolve: {
        alias: {
            vue: 'vue/dist/vue.js'
        },
        extensions: ['.js', '.vue']
    }
};

I already explain on top that we need “Entry” to configure the source of the js files with path to get the bundle later.

JavaScript
entry: { app: './wwwroot/js/app.js', home: './Views/Home/Index.cshtml.js'}

Output: This is the configuration of the output path and bundle name of compiled JavaScript files.

JavaScript
output: { publicPath: "/dest/js/", path: path.join(__dirname, '/wwwroot/dest/js/'),
        filename: '[name].bundle.js'}

If you want to compile and bundle the JS files using web-pack Task Runner Explorer, then make sure you install the Web-Pack Task Runner Explorer. If you don’t see the Task Runner Explorer, then select the webpack.config.js and click on the right button of the mouse. Now from the Task Runner Explorer, select the Run in the webpack.config.js and click on the right button of the mouse as shown in the below image. As a result, all of the JS files will be built to the output directory (wwwroot\dest\js).

Image 6

Why Drop-Zone?

It is easy to drag and drop a file onto it as well as to upload the file to the server; Light weight JavaScript library and minimum code requires to use it.

Adding Drop-Zone and Configuring in the JS and View File

  • To install dropzone package, add the dropzone into the devDependencies of the package.json file. "devDependencies": {vue2-dropzone": "2.0.0" }
  • If you open the webpack.config.js file, then you will find that I already add the JavaScript source file with the path into the entry. entry: {home: './Views/Home/Index.cshtml.js'}
  • In this project, find the ‘Index.cshtml’ View page and ‘Index.cshtml.js’ file into the View>Home directory. Open the Index.cshtml and add the dropzone and JavaScript bundle file. To add them, end up with following:

Image 7

In the dropzone:

  1. url: is used to send the posted file and it requires the path of the controller with the action method (“/Home/SubmitFile”).
  2. use-custom-dropzone-options: will be true if you want to customize the option; (I add the “useUploadOptions” variable in the Index.cshtml.js file.)
  3. dropzone-options: here you can customize the maxfiles, maxFileSizeInMB, acceptedFiles, dictDefaultMessage. (Find the “uploadOptions” in the Index.cshtml.js)
  4. v-on:vdropzone-success: This method is used after successfully uploading the file.
  5. v-on:vdropzone-error: This method is used if upload is failed.
  • The Index.cshtml.js file which is used into the Index.cshtml with bundle named home.bundle.js and end with the following:
    JavaScript
    import Vue from 'vue';
    import Dropzone from 'vue2-dropzone';
    
    document.addEventListener('DOMContentLoaded', function (event) {
        let view = new Vue({
            el: document.getElementById('view'),
            components: {
                "dropzone": Dropzone
            },
            data: {
                message: 'This is the index page',
                useUploadOptions: true,
                uploadOptions: {
                  acceptedFiles: '.png,.jpg,.pdf',
                  dictDefaultMessage: 'To upload the file click here. Or, drop a file here.',
                  maxFiles: 1,
                  maxFileSizeInMB: 20,
                  addRemoveLinks: true
                }
            },
            methods: {
                onUploaded: function (file, response) {
                    if (response.status === "OK" || response.status === "200") {
                        console.log('Successfully uploaded!');
                    }
                    else {
                        this.isVisible = false;
                        console.log(response.message);
                    }
                },
                onUploadError: function (file, message, xhr) {
                    console.log("Message ====> " + JSON.stringify(message));
                }
            }
        });
    });
  • Go to the home controller file and add the following code:
    C#
    [HttpPost("/Home/SubmitFile")]
    public async Task<ActionResult> SubmitFile(IFormFile file)
    {
           try
           {
                 //// To do: Validation
                 //// To do: check file-content
                 string webRootPath = hostingEnvironment.WebRootPath;
                 string fileLandingPath = Path.Combine(webRootPath, folderName);
    
                 StreamReader stream = new StreamReader(file.OpenReadStream());
    
                 if (!Directory.Exists(fileLandingPath))
                 {
                        Directory.CreateDirectory(fileLandingPath);
                 }
    
                 string filePath = string.Format("{0}\\{1}{2}", fileLandingPath,
                        Path.GetFileNameWithoutExtension(file.FileName), 
                        Path.GetExtension(file.FileName));
    
                 using (var fileStream = new FileStream(filePath, FileMode.Create))
                 {
                        await file.CopyToAsync(fileStream);
                 }
    
                 var jsonResult = Json(new { status = "OK" });
                 return jsonResult;
           }
           catch (Exception ex)
           {
                 return Json(new { status = "Error", message = ex.Message });
           }
    }
  • Now select the Web-pack Task Runner to compile and bundle the js files. Select the Run and right click on the mouse button, then you will find the run and Bindings options. Click on the Run. Wait few seconds, you will get the result in to the “wwwroot\dest\js” directory.

    Image 8

  • Now ready to run the application, after running, you will find the following upload control:

    Image 9

Note: In this article, I mainly focus on configuration and setup. So, I didn’t care about the latest version of the packages. You should use the latest version of the packages.

History

  • 15th February, 2020: Initial version

License

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