How To Build A REST API (Web Service) Application Using .NET Core, SQL, and HTML With JavaScript

In this blog, I am going to illustrate an end-to-end solution (service > back-end > front-end) to create a new .NET Core web service and consume that service by the front-end. I will be demonstrating step-by-step how to develop a RESTful Web Service application in ASP.NET Core and connect that service to SQL Server using Entity Framework and consume by front-end UI developed in HTML using JavaScript.
 
I will be creating a Training Service as an example in my complete course to demonstrate Web Service, Entity Framework, and a few front-end concepts. The front-end will provide a UI to list all the training details in table form using REST API and another form with input fields as name, start date, end date, and confirm Submit button. On confirmation, the REST API should save the new training details into the database.
 
Let's start with Visual Studio to create a new web service (REST) application using .NET Core.
 
1. Open VS, go to File > New and select Project > ASP .NET Core Web Application. Select the solution name (e.g. Training service) and the location of your local directory. Click ok.
 
 
2. Select the API for creating REST API using default example valuecontroller(can be deleted later). You can uncheck the 'Configure for HTTPS' checkbox because that creates SSL-based project and you have to use HTTPS instead of HTTP in your URLs (this is an optional step).
 
 
3. Click ok and you should see the below project structure.
 
 
4. Let's setup the Entity framework Model for sql server to create one table i.e. tblTraining having three properties Name(char[256)), StartDate(datetime), EndDate(datetime). 
  1. CREATE TABLE [dbo].[TblTraining] (  
  2.   
  3. [NameCHAR (256) NOT NULL,  
  4.   
  5. [StartDate] DATETIME NOT NULL,  
  6.   
  7. [EndDate] DATETIME NULL,  
  8.   
  9. PRIMARY KEY CLUSTERED ([NameASC)  
  10.   
  11. );  
You can use also VS to setup entity framework and setup the Model, I am not adding more steps here for entity framework and it is not the scope of this article. Once your Model is ready take the connection string.
 
If you already have any existing framework then just add this new table for test and execute the below command.
  1. scaffold-DBContext "your connection string which start with Data Source= ……………….." Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -tables tblTraining  
  1. public partial class tempdbContext : DbContext  
  2. {  
  3.     public tempdbContext()  
  4.     {  
  5.     }  
  6.   
  7.     public tempdbContext(DbContextOptions<tempdbContext> options)  
  8.         : base(options)  
  9.     {  
  10.     }  
  11.   
  12.     public virtual DbSet<TblTraining> TblTraining { getset; }  
  13.   
  14.     protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)  
  15.     {  
  16.         if (!optionsBuilder.IsConfigured)  
  17.         {  
  18. #warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.  
  19.             optionsBuilder.UseSqlServer("Data Source=(localdb)\\LocalUAP;Initial Catalog=tempdb;Integrated Security=True");  
  20.         }  
  21.     }  
  22.   
  23.     protected override void OnModelCreating(ModelBuilder modelBuilder)  
  24.     {  
  25.         modelBuilder.HasAnnotation("ProductVersion""2.2.4-servicing-10062");  
  26.   
  27.         modelBuilder.Entity<TblTraining>(entity =>  
  28.         {  
  29.             entity.HasKey(e => e.Name);  
  30.   
  31.             entity.Property(e => e.Name)  
  32.                 .HasMaxLength(256)  
  33.                 .IsUnicode(false)  
  34.                 .ValueGeneratedNever();  
  35.   
  36.             entity.Property(e => e.EndDate).HasColumnType("date");  
  37.   
  38.             entity.Property(e => e.StartDate).HasColumnType("date");  
  39.         });  
  40.     }  
  41. }  
  1. public partial class TblTraining  
  2. {  
  3.     public string Name { getset; }  
  4.     public DateTime StartDate { getset; }  
  5.     public DateTime? EndDate { getset; }  
  6. }  
  7.   
  8. public class TrainingViewModel  
  9. {  
  10.     public string EndDate { getset; }  
  11.   
  12.     public string StartDate { getset; }  
  13.   
  14.     public string Name { getset; }  
  15. }  
5. Open the Startup.cs and setup the connection with the database for this webservice. In my case, my database name is tempdb which created tempdbContext. Add below code in your ConfigureServices method.
  1. // This method gets called by the runtime. Use this method to add services to the container.  
  2. public void ConfigureServices(IServiceCollection services)  
  3. {  
  4.     services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);  
  5.   
  6.     var connection = "your connection string here start with Data Source=….";  
  7.     services.AddDbContext<tempdbContext>(o => o.UseSqlServer(connection));  
  8.   
  9.     services.AddScoped<ITrainingServices, TrainingServices>();  
  10. }  
6. Next, you can use the internal services/helper concept to read/validate the data when service requests for it. I have created ITrainingServices interface and corresponding service class TrainingServices which use database context to manage the data. Using this approach, you can also create one local service (LocalTrainingServices) which is independent of db context, and keeps values in memory for testing. If you have not established entity framework yet in that case you can use this local service as Scope in startup.cs. Replace AddScoped<> line in startup.cs with below code.
 
         services.AddScoped<ITrainingServices, LocalTrainingServices>(); 
  1. public interface ITrainingServices  
  2. {  
  3.     Task<IList<TrainingViewModel>> GetTrainingData();  
  4.   
  5.     TrainingViewModel GetTrainingData(string name);  
  6.   
  7.     bool CreateTraining(TrainingViewModel viewModel);  
  8.   
  9.     void Delete(string name);  
  10. }  
  1. public class TrainingServices : ITrainingServices  
  2. {  
  3.     private readonly tempdbContext dbcontext;  
  4.   
  5.     public TrainingServices(tempdbContext context)  
  6.     {  
  7.         this.dbcontext = context;  
  8.     }  
  9.   
  10.     public async Task<IList<TrainingViewModel>> GetTrainingData()  
  11.     {  
  12.         return await dbcontext.TblTraining.Select(s => new TrainingViewModel() { Name = s.Name, StartDate = s.StartDate.ToString(), EndDate = s.EndDate.ToString() }).ToListAsync();  
  13.     }  
  14.   
  15.     public TrainingViewModel GetTrainingData(string name)  
  16.     {  
  17.         var s = dbcontext.TblTraining.FirstOrDefault(d => d.Name == name);  
  18.         if (s == null)  
  19.         {  
  20.             return null;  
  21.         }  
  22.   
  23.         return new TrainingViewModel { Name = s.Name, StartDate = s.StartDate.ToString(), EndDate = s.EndDate.ToString() };  
  24.     }  
  25.   
  26.     public async void Delete(string name)  
  27.     {  
  28.         var s = dbcontext.TblTraining.FirstOrDefault(d => d.Name == name);  
  29.         if (s == null)  
  30.         {  
  31.             return;  
  32.         }  
  33.   
  34.         dbcontext.TblTraining.Remove(s);  
  35.         await dbcontext.SaveChangesAsync();  
  36.     }  
  37.   
  38.     public bool CreateTraining(TrainingViewModel viewModel)  
  39.     {  
  40.         try  
  41.         {  
  42.             var start = DateTime.Parse(viewModel.StartDate);  
  43.             var end = DateTime.Parse(viewModel.EndDate);  
  44.             if (start < end)  
  45.             {  
  46.                 return false;  
  47.             }  
  48.   
  49.             dbcontext.TblTraining.Add(new TblTraining() { Name = viewModel.Name, StartDate = start, EndDate = end });  
  50.             int count = dbcontext.SaveChanges();  
  51.             if (count > 0)  
  52.             {  
  53.                 return true;  
  54.             }  
  55.   
  56.             return false;  
  57.         }  
  58.         catch (Exception ex)  
  59.         {  
  60.             return false;  
  61.         }  
  62.     }  
  63. }  
  1. public class LocalTrainingServices : ITrainingServices  
  2. {  
  3.     private static readonly List<TrainingViewModel> trainingViewModels = new List<TrainingViewModel>()  
  4.     {  
  5.         new TrainingViewModel() {Name = "c#", StartDate = "2012-01-01", EndDate = "2012-12-01"},  
  6.         new TrainingViewModel() {Name = "java", StartDate = "2013-01-01", EndDate = "2014-12-01"},  
  7.         new TrainingViewModel() {Name = "python", StartDate = "2018-01-01", EndDate = "2018-12-01"},  
  8.     };  
  9.   
  10.     public Task<IList<TrainingViewModel>> GetTrainingData()  
  11.     {  
  12.         return new Task<IList<TrainingViewModel>>(() => trainingViewModels);  
  13.     }  
  14.   
  15.     public TrainingViewModel GetTrainingData(string name) =>  
  16.         trainingViewModels.FirstOrDefault(d => d.Name == name);  
  17.   
  18.     public void Delete(string name)  
  19.     {  
  20.         var s = trainingViewModels.FirstOrDefault(d => d.Name == name);  
  21.         if (s == null)  
  22.         {  
  23.             return;  
  24.         }  
  25.   
  26.         trainingViewModels.Remove(s);  
  27.     }  
  28.   
  29.     public bool CreateTraining(TrainingViewModel viewModel)  
  30.     {  
  31.         if (GetTrainingData(viewModel.Name) == null)  
  32.         {  
  33.             trainingViewModels.Add(viewModel);  
  34.             return true;  
  35.         }  
  36.   
  37.         return false;  
  38.     }  
  39. }  
7. Now, let's start the real implementation of REST api/web service. Create new controller by right clicking on Controller folder => Add => Controller. Select the once which matches to our case; if you want to map your model entity with controller directly then you can choose the last option; i.e., API controller with action using entity framework. But in my case, I am taking API controller with read/write actions. Select name TrainingController as this will be used in final URL name to access the service.
 
 
Main Controller Class.
  1. [Route("api/[controller]")]  
  2.     [ApiController]  
  3.     public class TrainingController : ControllerBase  
  4.     {  
  5.         private readonly ITrainingServices _trainingService;  
  6.   
  7.         public TrainingController(ITrainingServices trainingService)  
  8.         {  
  9.             _trainingService = trainingService;  
  10.         }  
  11.   
  12.         // GET: api/Training  
  13.         [HttpGet]  
  14.         public async Task<IEnumerable<TrainingViewModel>> Get()  
  15.         {  
  16.             return await _trainingService.GetTrainingData();  
  17.         }  
  18.   
  19.         // GET: api/Training/5  
  20.         [HttpGet("{name}", Name = "Get")]  
  21.         public TrainingViewModel Get(string name) => _trainingService.GetTrainingData(name);
  22.   
  23.         // POST: api/Training  
  24.         [HttpPost]  
  25.         public void Post(TrainingViewModel value) => _trainingService.CreateTraining(value);
  26.   
  27.         // DELETE: api/ApiWithActions/5  
  28.         [HttpDelete("{name}")]  
  29.         public void Delete(string name)  
  30.         {  
  31.             _trainingService.Delete(name);  
  32.         }  
  33.     }  
8. Well, we are done with web service using REST(i.e. HttpGet, HttpPost etc) and you can deploy this service either in IIS or as locally from VS, select the service name and click on run green button. You must be finally getting the url for this service something like https://localhost:yourportno[default:5001]/api/Training. Here the item is training; i.e. controller name to access the service.
 
 
9. Service is running now, let's try to consume this service. Before writing the UI part let's check if the service is really working, you can use Chrome extension "ARC" or postman like tool to verify it. Just paste the URL and check the response.
 
 
 
10. Let's write one small front end application to load this data in HTML and using javascript. Here is the code.
  1. <!DOCTYPE html>  
  2.   
  3. <html lang="en" xmlns="http://www.w3.org/1999/xhtml">  
  4. <head>  
  5.     <meta charset="utf-8" />  
  6.     <title>Training</title>  
  7.     <!--Styles from Bootstrap-->  
  8.     <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">  
  9. </head>  
  10. <body>  
  11.     <!--<header>Traning Details</header>-->  
  12.     <div id="header"></div>  
  13.     <main class="container">  
  14.         <table class="table">  
  15.         <thead>  
  16.             <tr>  
  17.                 <th>  
  18.                     Training Name  
  19.                 </th>  
  20.                 <th>  
  21.                     Start Date  
  22.                 </th>  
  23.                 <th>  
  24.                     End Date  
  25.                 </th>  
  26.                 <th></th>  
  27.             </tr>  
  28.         </thead>  
  29.         <tbody class="tbody">  
  30.         </tbody>  
  31.     </table>  
  32.   
  33.     <div>  
  34.        <!--Get : Query string /url  
  35.         Post : Hidden fields-->  
  36.         <form method="get" id="form">  
  37.             <label>Training Name:</label>  
  38.             <input id="name" type="text" width="20"  placeholder="enter Traning name" required/> <br />  
  39.       
  40.             <label>Start Date     :</label>  
  41.             <input id="startdate" type="datetime" width="20"  data-provide="datepicker" /> <br />  
  42.       
  43.             <label>End Date       :</label>  
  44.             <input id="enddate" type="datetime" width="20" data-provide="datepicker"/><br />  
  45.   
  46.             <input type="submit" value="Submit"/>  
  47.               
  48.         </form>  
  49.     </div>  
  50.   
  51.     <div id="footer"></div>  
  52.     <!--<footer>End of Tranings Details</footer>-->  
  53.     <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>  
  54.     <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>  
  55.   
  56.     <!--JQuery-->  
  57.     <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>  
  58.   
  59.     <script type="text/javascript" charset="utf8" src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.3/jstree.min.js"></script>  
  60.     <script src="main.js"></script>  
  61.   
  62.     </main>  
  63. </body>  
  64. </html>  
  1. // JavaScript source code  
  2. 'use strict'  
  3. $(document).ready(function ()  
  4. {  
  5.     getTraningData();  
  6. });  
  7.   
  8. $('form').submit(function (e) {  
  9.     e.preventDefault();  
  10.     const data = {  
  11.         Name: $('#name').val(),  
  12.         Startdate: $('#startdate').val(),  
  13.         EndDate: $('#enddate').val()  
  14.     }  
  15.   
  16.     let tag = '<tr><td>' + data.Name + '</td>';  
  17.     tag += '<td>' + data.Startdate + '</td>';  
  18.     tag += '<td>' + data.Enddate + '</td></tr>';  
  19.     $('table>tbody').append(tag);  
  20.   
  21.     const api = 'https://localhost:5001/api/training'  
  22.     console.log(data);  
  23.     $.post(api, { Name: data.Name, Startdate:data.Startdate, EndDate:data.EndDate });  
  24. });  
  25.   
  26. function getTraningData() {  
  27.     const api = 'https://localhost:5001/api/training'  
  28.     $.getJSON(api).then(function (data) {  
  29.         console.log(data);  
  30.         for (var i = 0, len = data.length; i < len; i++) {  
  31.   
  32.             $('table>tbody').append(createTraining(data[i]));  
  33.             }  
  34.         }).catch(function (err) {  
  35.             console.log(err);  
  36.         });  
  37. }  
  38.   
  39. function createTraining(training) {  
  40.     let tag = `  
  41.         <tr>  
  42.             <td>  
  43.                 ${training.name}  
  44.             </td>  
  45.             <td>  
  46.                 ${training.startDate}  
  47.             </td>  
  48.             <td>  
  49.                ${training.endDate}  
  50.             </td>  
  51.         </tr>  
  52.     `;  
  53.   
  54.     return tag;  
  55. }  
Final output with SQL server data.
 
 
I hope you liked this blog. Let me know any questions you might have in the comments section. Thanks!