- สร้างโปรเจ็กส์ด้วย Visual Studio 2019
- ไฟล์ต่างๆในโปรเจ็กส์
- เพิ่มคลาส Movie
- สร้างคอนโทรลเลอร์ MovieController
- ติดตั้ง Pomelo.EntityFrameworkCore.MySql
- สร้างตารางที่ MySQL
- ทดสอบ API
1.สร้างโปรเจ็กส์ด้วย Visual Studio 2019
สร้างโปรเจ็กส์ใหม่ เลือก Create a new project
เลือกภาษา C#
เลือก ASP.NET Core Web Application
ตั้งชื่อโปรเจ็กส์ WebApiDemo เสร็จแล้วกด Create
เลือก template เป็น API และที่ด้านบนเลือกเป็น .NET Core และ ASP.NET Core 3.0
รันทดสอบ จะไปที่ http://localhost:52744/weatherforecast และได้ค่า
[ { "date": "2019-11-09T15:36:53.0790529+07:00", "temperatureC": 29, "temperatureF": 84, "summary": "Cool" }, { "date": "2019-11-10T15:36:53.0814444+07:00", "temperatureC": 23, "temperatureF": 73, "summary": "Chilly" }, { "date": "2019-11-11T15:36:53.0814498+07:00", "temperatureC": 6, "temperatureF": 42, "summary": "Cool" }, { "date": "2019-11-12T15:36:53.0814502+07:00", "temperatureC": 6, "temperatureF": 42, "summary": "Chilly" }, { "date": "2019-11-13T15:36:53.0814502+07:00", "temperatureC": -11, "temperatureF": 13, "summary": "Balmy" } ]
2.ไฟล์ต่างๆในโปรเจ็กส์
ไฟล์ WeatherForecast.cs
คลาส WeatherForecast
using System; namespace WebApiDemo { public class WeatherForecast { public DateTime Date { get; set; } public int TemperatureC { get; set; } public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); public string Summary { get; set; } } }
ไฟล์ Controllers/WeatherForecastController.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; namespace WebApiDemo.Controllers { [ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; private readonly ILogger<WeatherForecastController> _logger; public WeatherForecastController(ILogger<WeatherForecastController> logger) { _logger = logger; } [HttpGet] public IEnumerable<WeatherForecast> Get() { var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }) .ToArray(); } } }
ไฟล์ Startup.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace WebApiDemo { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllers(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }
ไฟล์ Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace WebApiDemo { public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); } }
ไฟล์ appsettings.json
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*" }
ไฟล์ Properties/launchSettings.json
{ "$schema": "http://json.schemastore.org/launchsettings.json", "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { "applicationUrl": "http://localhost:52744", "sslPort": 0 } }, "profiles": { "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, "launchUrl": "weatherforecast", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, "WebApiDemo": { "commandName": "Project", "launchBrowser": true, "launchUrl": "weatherforecast", "applicationUrl": "http://localhost:5000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } }
3.เพิ่มคลาส Movie
สร้างโฟลเดอร์ Models
สร้างไฟล์ Models/Movie.cs
using System; using System.ComponentModel.DataAnnotations; namespace WebApiDemo.Models { public class Movie { public int Id { get; set; } public string Title { get; set; } [DataType(DataType.Date)] public DateTime ReleaseDate { get; set; } public string Genre { get; set; } public decimal Price { get; set; } } }
4.สร้างคอนโทรลเลอร์ MovieController
คลิกขวาที่โฟลเดอร์ Controllers เลือก Add | Controller…
เลือก API Controller with actions, using Entity Framework
Model class เลือก Movie
Data context class สร้างใหม่ชื่อ MovieContext
กด Add
เสร็จแล้วจะได้ไฟล์ Data/MovieContext.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; namespace WebApiDemo.Models { public class MovieContext : DbContext { public MovieContext (DbContextOptions<MovieContext> options) : base(options) { } public DbSet<WebApiDemo.Models.Movie> Movie { get; set; } } }
และได้ไฟล์ Controllers/MoviesController.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using WebApiDemo.Models; namespace WebApiDemo.Controllers { [Route("api/[controller]")] [ApiController] public class MoviesController : ControllerBase { private readonly MovieContext _context; public MoviesController(MovieContext context) { _context = context; } // GET: api/Movies [HttpGet] public async Task<ActionResult<IEnumerable<Movie>>> GetMovie() { return await _context.Movie.ToListAsync(); } // GET: api/Movies/5 [HttpGet("{id}")] public async Task<ActionResult<Movie>> GetMovie(int id) { var movie = await _context.Movie.FindAsync(id); if (movie == null) { return NotFound(); } return movie; } // PUT: api/Movies/5 // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see https://aka.ms/RazorPagesCRUD. [HttpPut("{id}")] public async Task<IActionResult> PutMovie(int id, Movie movie) { if (id != movie.Id) { return BadRequest(); } _context.Entry(movie).State = EntityState.Modified; try { await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!MovieExists(id)) { return NotFound(); } else { throw; } } return NoContent(); } // POST: api/Movies // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see https://aka.ms/RazorPagesCRUD. [HttpPost] public async Task<ActionResult<Movie>> PostMovie(Movie movie) { _context.Movie.Add(movie); await _context.SaveChangesAsync(); return CreatedAtAction("GetMovie", new { id = movie.Id }, movie); } // DELETE: api/Movies/5 [HttpDelete("{id}")] public async Task<ActionResult<Movie>> DeleteMovie(int id) { var movie = await _context.Movie.FindAsync(id); if (movie == null) { return NotFound(); } _context.Movie.Remove(movie); await _context.SaveChangesAsync(); return movie; } private bool MovieExists(int id) { return _context.Movie.Any(e => e.Id == id); } } }
และเมื่อกลับไปดูที่ไฟล์ appsettings.json จะเห็นว่ามีการเพิ่ม ConnectionStrings
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", "ConnectionStrings": { "MovieContext": "Server=(localdb)\\mssqllocaldb;Database=MovieContext-325717dc-d87d-4e13-9f43-362cef94252e;Trusted_Connection=True;MultipleActiveResultSets=true" } }
แก้ไขจาก MS SQL เป็น MySQL ดังนี้
"ConnectionStrings": { "MovieContext": "server=localhost;port=3306;database=mydbname;uid=myusername;password=mypassword" }
และที่ไฟล์ Startup.cs มีโค๊ดเชื่อมต่อ MS SQL เข้ามา
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddDbContext<MovieContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MovieContext"))); }
5.ติดตั้ง Pomelo.EntityFrameworkCore.MySql
- nuget Pomelo.EntityFrameworkCore.MySql
- nuget MySql.Data.EntityFrameworkCore (This package has been deprecated.)
- nuget MySql.EntityFrameworkCore
- nuget MySql.Data (Oracle)
PM> Install-Package Pomelo.EntityFrameworkCore.MySql -Version 3.0.0-rc3.final
แก้ไขเป็นเชื่อมต่อไปที่ MySql แทน
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddDbContext<MovieContext>(options => options.UseMySql(Configuration.GetConnectionString("MovieContext"))); }
6.สร้างตารางที่ MySQL
CREATE TABLE `movie` ( `Id` int(11) NOT NULL, `Title` longtext DEFAULT NULL, `ReleaseDate` datetime(6) NOT NULL, `Genre` longtext DEFAULT NULL, `Price` decimal(65,30) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `movie` ADD PRIMARY KEY (`Id`); COMMIT;
เพิ่มข้อมูลตัวอย่าง
INSERT INTO `movie` (`Id`, `Title`, `ReleaseDate`, `Genre`, `Price`) VALUES (0, 'X-Men', '2019-11-01 00:00:00.000000', 'Action', '1.000000000000000000000000000000');
7.ทดสอบ API
เรียกไปที่ http://localhost:52744/api/movies จะได้
[ { "id": 0, "title": "X-Men", "releaseDate": "2019-11-01T00:00:00", "genre": "Action", "price": 1.0000000000000000000000000000 } ]