Crud with ASP.NET Web API in MVC using Vue.js/CLI

Hello Guys, Today I will show you how to perform crud in MVC using Vue.js/cli. I created a sample project with Vue.js and ASP.NET MVC 4.6.1 that has all CRUD operations. I want to share the code here.

If you have not heard about vue.js you can refer this article https://www.thecodehubs.com/introduction-to-vuejs/

Getting started

  • The project has two main parts. a Back-end which I used ASP.NET MVC 4.6.1 and Front-end which I used Vue.js/CLI 2.x . I started with the empty template and added features as I needed. For database I used SSMS(SQL Server Management Studio) and Entity Framework.
  • if you have not installed and setup vue.js/CLI, you can refer this article https://www.thecodehubs.com/how-to-install-and-setup-vue-js/

Roadmap for perform crud operation in MVC using vue.js/CLI

  1. Install Vuetify.js : the world’s most popular Vue.js framework for building feature rich, blazing fast applications.
  2. install axios : Axios is an HTTP client library.
  3. Concept of event bus : using event bus in vue.js to pass data between components.
  4. Front-end : Vue.js/CLI 2.x.
  5. Back-end : ASP.NET MVC Web API 4.6.1

1) Install Vuetify.js

  • Vuetify.js is the most complete user interface component library for Vue.js applications that follows the Google Material Design specs. Let’s quickly dive in and look at how you can get started.
  • Open CMD and navigate to your project folder write: vue add vuetify

  • Choose a Preset: Default(recommended).
  • After successfully installation of vuetify.js open your project in visual studio code, you can seen that vuetify.js plugin installed.

2) Install axios

  • Axios is an HTTP client library. It uses promises by default and runs on both the client and the server, which makes it appropriate for fetching data during server-side rendering. Because it uses promises, you can combine it with async/await to get a concise and easy-to-use API.
  • Open CMD > navigate to your project folder > Command: npm install axios –save
  • Your main.js file looks like given below:

3) Installation of event bus

  • Essentially, an event bus is a Vue.js instance that can emit events in one component, and then listen and react to the emitted event in another component directly — without the help of a parent component.
  • By definition, using an event bus is more efficient than using event emitters because it requires less code to run.
  • We’re going to create an event bus instance as a separate file, import it into the two components that are going to share data, and then allow the components to communicate through this shared instance in a safe, private channel.
  • This is commonly known as the publish-subscribe approach.
  • Open CMD > Navigate to your project folder > command: npm install vue-bus –save
  • import vue-bus in main.js file:
  • import VueBus from 'vue-bus';
    Vue.use(VueBus);

     

4) Lets move on front-end

  • First of all we will create three component:
  1. Registrationform.vue
  2. Displaydata.vue
  3. Dialogs.vue
1) Registrationform.vue:
<template>
  <v-form v-model="valid" ref="form">
    <v-container>
      <v-row>
        <v-col
          cols="12"
          md="4"
        >
          <v-text-field
            v-model="FirstName"
            :rules="nameRules"
            :counter="10"
            label="First name"
            required
          ></v-text-field>
        </v-col>

        <v-col
          cols="12"
          md="4"
        >
          <v-text-field
            v-model="LastName"
            :rules="nameRules"
            :counter="10"
            label="Last name"
            required
          ></v-text-field>
        </v-col>

        <v-col
          cols="12"
          md="4"
        >
          <v-text-field
            v-model="Message"
            label="Message"
            required
          ></v-text-field>
        </v-col>
        
      </v-row>
      <v-row>
          <v-col cols="12" md="4">
              <div class="my-2">
                    <v-btn color="primary" @click="onSubmit()">Submit</v-btn>
                </div>
             </v-col>
        </v-row>
        <v-row>
          <v-col cols="12" md="12">
            <displaydata/>
            </v-col>
        </v-row>
    </v-container>
  </v-form>
</template>

<script> 
import { postData } from '@/services/module.js'
import { getData } from '@/services/module.js'
import displaydata from '@/components/displaydata.vue'
  export default {
    name:'registrationform',
    components:{
      displaydata
    },
   
    data: () => ({
      valid: false,
      FirstName: '',
      LastName: '',
      Message: '',
      showUserInfo:[],
      nameRules: [
        v => !!v || 'Name is required',
        v => v.length <= 10 || 'Name must be less than 10 characters',
      ],
      
      
    }),
    methods:{
        onSubmit:function(){
           const event=new FormData();
           event.append("FirstName",this.FirstName);
           event.append("LastName",this.LastName);
           event.append("Message",this.Message);
            postData(event).then(response=>{
                if(response.data){
                    this.loadData();
                    alert("Data Inserted Successfully");
                    this.$refs.form.reset();  
                }
            }).catch(error=>{
                console.log(error);
                this.error=true;
            })
        },
        loadData:function(){
                getData().then(response=>{
                    this.showUserInfo=response.data;
                    this.$bus.$emit('display-all-user-information',this.showUserInfo)
                }).catch(error=>{
                    console.log(error);
                    this.error=true;
                })
        }
    },
    mounted:function(){
      this.loadData();
      this.$bus.$on('display-record',this.loadData);
    }
   
  }
</script>
2) Displaydata.vue:
<template>
  <v-simple-table>
    <template v-slot:default>
      <thead>
        <tr>
          <th class="text-left">Id</th>
          <th class="text-left">FirstName</th>
          <th class="text-left">LastName</th>
          <th class="text-left">Message</th>
          <th class="text-center">Action</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="data in allUserData" :key="data.id">
          <td>{{ data.id }}</td>
          <td>{{ data.FirstName }}</td>
          <td>{{ data.LastName }}</td>
          <td>{{ data.Message }}</td>
          <td>
               <dialogs :id="data.id"></dialogs>  
           </td>
         
        </tr>
      </tbody>
    </template> 
  </v-simple-table>
</template>
<script>
import dialogs from '@/components/dialogs.vue'
export default({
    name:'displaydata',

    components:{
        dialogs
    },
    data:function(){
        return{
            allUserData:[],
        }
    },
    mounted:function(){
        this.$bus.$on('display-all-user-information',this.displayUserInformation); 
    },
    methods:{
        displayUserInformation:function(info){
            this.allUserData=info;
        },
        
    }
})
</script>
3) Dialogs.vue:
<template>
  <v-row justify="center">
    <v-dialog
      v-model="dialog"
      persistent
      max-width="50%"
    >
      <template v-slot:activator="{ on, attrs }" class="text-center">
        <v-btn fab small class="primary white--text mr-3" v-on="on" v-bind="attrs" @click="onEdit(id)"><v-icon small color="white darken-2"> mdi-pencil</v-icon></v-btn> 
        <v-btn fab small class="error white--text"  v-on="on" v-bind="attrs" @click="onDelete()"><v-icon small color="white">mdi-trash-can </v-icon></v-btn>
      </template>
      <v-card>
        <v-card-title class="headline">
            {{isFormVisible ? 'Edit User Information' : 'Delete User Record'}}
        </v-card-title>
        <v-card-text>
            <h3 v-if="!isFormVisible">Are you sure want to delete this User ID <span class="font-weight-bold">:{{id}}</span></h3>
  <v-form v-model="valid" v-if="isFormVisible">
    <v-container>
      <v-row>
           <v-col
          cols="12"
          md="6"
        >
          <v-text-field
            v-model="hiddenId"
            disabled
            label="User ID"
          ></v-text-field>
        </v-col>

        <v-col
          cols="12"
          md="6"
        >
          <v-text-field
            v-model="FirstName"
            :rules="nameRules"
            :counter="10"
            label="First name"
            required
          ></v-text-field>
        </v-col>

        <v-col
          cols="12"
          md="6"
        >
          <v-text-field
            v-model="LastName"
            :rules="nameRules"
            :counter="10"
            label="Last name"
            required
          ></v-text-field>
        </v-col>

        <v-col
          cols="12"
          md="6"
        >
          <v-text-field
            v-model="Message"
            label="Message"
            required
          ></v-text-field>
        </v-col>
      </v-row>
    </v-container>
  </v-form>
      </v-card-text>
        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn
            color="green darken-1"
            text
            v-if="isUpdateVisible"
            @click="saveData()"
          >
            Update
          </v-btn>
           <v-btn
            color="red darken-1"
            text
            v-if="!isUpdateVisible"
            @click="deleteUserInfo(id)"
          >
            Delete
          </v-btn>
          <v-btn
            color="green darken-1"
            text
            @click="onClose()"
          >
            Close
          </v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </v-row>
</template>
<script>
import { UpdateData } from '@/services/module.js'
import { saveUpdateData } from '@/services/module.js'
import { DeleteData } from '@/services/module.js'

  export default {
      name:'dialogs',
      props:{
          id:Number,
          isFormVisible:{
              type:Boolean,
              default:true
          },
          isUpdateVisible:{
              type:Boolean,
              default:true
          },
         
      },
    data () {
      return {
        dialog: false,
        valid: false,
        FirstName: '',
        LastName: '',
        Message: '',
        showUserInfo:[],
        hiddenId:'',
        nameRules: [
        v => !!v || 'Name is required',
        v => v.length <= 10 || 'Name must be less than 10 characters',
      ],
      }
    },
    methods:{
        onEdit:function(id){
                UpdateData(id).then(response=>{
                        this.hiddenId=response.data.id;
                        this.FirstName=response.data.FirstName;
                        this.LastName=response.data.LastName;
                        this.Message=response.data.Message;
                        
                }).catch(error=>{
                    console.log(error);
                    this.error=true;
                })
        },
        saveData:function(){
            const event=new FormData();
            event.append("id",this.hiddenId);
            event.append("FirstName",this.FirstName);
            event.append("LastName",this.LastName);
            event.append("Message",this.Message);
            saveUpdateData(event).then(response=>{
                if(response.data){
                    this.dialog=false;
                    this.$bus.$emit('display-record');
                }
            }).catch(error=>{
                console.log(error);
                this.error=true;
            })
        },
        onDelete:function(){
             if(confirm){
                this.isFormVisible=false;
                this.isUpdateVisible=false;
            }
        },
        deleteUserInfo:function(id){
            DeleteData(id).then(response=>{
                    if(response.data){
                        this.dialog=false;
                        this.$bus.$emit('display-record');
                    }
                })
        },
        onClose:function(){
            this.dialog=false;
            this.isFormVisible=true;
            this.isUpdateVisible=true;
        }
        
    }
  }
</script>
  • Create services folder that contains two files as is given below:

  1. api.js
  2. module.js
1) api.js:
import axios from 'axios'
const state={
    POST:'POST',
    GET:'GET',
    PUT:'PUT',
    DELETE:'DELETE',
    URL: 'http://localhost:56481/api/', //your web api project URL
}
export default{
    state,
    axios,
}
2) module.js:
const api=require('./api');
var server=api.default.axios;
var POST=api.default.state.POST;
var URI=api.default.state.URL;
var GET=api.default.state.GET;
var DELETE=api.default.state.DELETE;

export function postData(data){
    const Api_Request=server({
      method : POST,
      url : URI + 'posting/posted', data
    });
    return Api_Request;

}

export function getData(){
  const Api_Request=server({
    method:GET,
    url : URI + 'posting/Getdata',
  });
  return Api_Request;
}

export function UpdateData(id){
  const Api_Request=server({
    method : GET,
    url : URI + 'posting/Updatedata?id='+ id
    
  });
  return Api_Request;
}

export function saveUpdateData(data){
  const Api_Request=server({
    method : POST,
    url : URI + 'posting/SaveUpdateData', data
    
  });
  return Api_Request;
}

export function DeleteData(id){
  const Api_Request=server({
    method : DELETE,
    url : URI + 'posting/DeleteUserData?id='+ id
    
  });
  return Api_Request;
}
  • Your App.vue file looks like as it is given below:
  • import your component file in App.vue.

App.vue:

<template>
  <v-app>
    <v-app-bar
      app
      color="primary"
      dark
    >
      <div class="d-flex align-center">
       <div display-1>User Registration</div>
      </div>
      <v-spacer></v-spacer>
      <v-btn
        href="https://github.com/vuetifyjs/vuetify/releases/latest"
        target="_blank"
        text
      >
        <span class="mr-2">Latest Release</span>
        <v-icon>mdi-open-in-new</v-icon>
      </v-btn>
    </v-app-bar>
    <v-main>
     <registrationform/>
    </v-main>
  </v-app>
</template>

<script>
import registrationform from '@/components/registrationform.vue'

export default {
  name: 'App',
  components: {
    registrationform,
  },

  data: () => ({
    //
  }),
};
</script>

5) Lets move on back-end

  • Create Database
  • Create table
  • Now in this project we will use database first approach so we need to create a database and a table. Here I created a database name with vueDB and table contact with the following columns as you can see in the below image.

  • Create New Asp.net MVC project with web API
  • Now we need to add ADO.Net Entity Data Model in our project. For adding ADO.Net Entity Data Model click on your project name then click on Add and then click on new Item or you can use short cut key Ctrl+Shift+A .
  • after adding ADO.NET Entity Data Model , Entity Framework creates an  edmx file in your project as you can see in the below image.

  • Here is contact Model

  • Open WebApiConfig.cs file which is appear in App_start folder and add the following code in it.

  • Create Web API contact controller and add the following code in it
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using vuecrudapi.Models;

namespace vuecrudapi.Controllers
{
    [RoutePrefix("api/posting")]
    public class ContactController : ApiController
    {
        public vueDBEntities _context = new vueDBEntities();
        public contact contact = new contact();

        [HttpPost]
        [Route("posted")]
        public HttpResponseMessage Post()
        {
            
              var _request = System.Web.HttpContext.Current.Request;
              string FirstName = _request.Form["FirstName"];
              string LastName = _request.Form["LastName"];
              string Message = _request.Form["Message"];
              contact.FirstName = FirstName;
              contact.LastName = LastName;
              contact.Message = Message;
              _context.contacts.Add(contact);
              _context.SaveChanges();
              var response = Request.CreateResponse(HttpStatusCode.OK, contact);
              return (response);
          
        }
        [HttpGet]
        [Route("Getdata")]
        public IHttpActionResult Get()

        {
                var getUserData = _context.contacts.Select(x => new
                {
                    x.id,
                    x.FirstName,
                    x.LastName,
                    x.Message,
                }).ToList();
           
            return Ok(getUserData);
           
        }
        [HttpGet]
        [Route("Updatedata")]
        public IHttpActionResult Edit(int id)

        {
            var isDataExist = _context.contacts.Where(x => x.id == id).Select(x => new
            {
                x.id,
                x.FirstName,
                x.LastName,
                x.Message,

            }).FirstOrDefault();
            return Ok(isDataExist);

        }
        [HttpPost]
        [Route("SaveUpdateData")]
        public HttpResponseMessage Update()

        {
            
            var _request = System.Web.HttpContext.Current.Request;
            string UserId = _request.Form["id"];
            string FirstName = _request.Form["FirstName"];
            string LastName = _request.Form["LastName"];
            string Message = _request.Form["Message"];
            contact.id = Convert.ToInt32(UserId);
            contact.FirstName = FirstName;
            contact.LastName = LastName;
            contact.Message = Message;
            var existingUser = _context.contacts.Where(x => x.id == contact.id).FirstOrDefault();
            if (existingUser!=null)
            {
                existingUser.id = Convert.ToInt32(UserId);
                existingUser.FirstName =FirstName;
                existingUser.LastName = LastName;
                existingUser.Message = Message;
                _context.SaveChanges();
                var response = Request.CreateResponse(HttpStatusCode.OK, existingUser);
                return response;
            }
            else
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Not found");
            }

            
        }
        [HttpDelete]
        [Route("DeleteUserData")]
        public HttpResponseMessage DeleteUserRecord(int id)
        {

            try {
                var UserExist = _context.contacts
                    .Where(s => s.id == id)
                    .FirstOrDefault();

                _context.Entry(UserExist).State = System.Data.Entity.EntityState.Deleted;
                _context.SaveChanges();
                var response = Request.CreateResponse(HttpStatusCode.OK, "Success");
                return (response);
            }
            catch(Exception ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
            }

        }
    }
}

Output:

 

I hope guys my article will help you to perform crud in vue.js, also share this article with your friends.

Submit a Comment

Your email address will not be published. Required fields are marked *

Subscribe

Select Categories