ฉันพูดถึงวิธีโหลดรูปภาพใน Reactjs ด้วย Asp.Net Core WebAPI เรากำลังสร้าง Asp.Net Core web API และสร้างฐานข้อมูลเซิร์ฟเวอร์ SQL ด้วยแกนเฟรมเวิร์กเอนทิตี จากนั้นฉันก็สร้างตัวควบคุม asp.net Core API สำหรับการโหลดรูปภาพ
เราสร้างแอปพลิเคชันฝั่งไคลเอ็นต์ใน Reactjs แบบฟอร์มที่มีโปรแกรมอัปโหลดรูปภาพได้รับการออกแบบมาเพื่อการนี้ ภาพตัวอย่างที่เลือกจะแสดงแยกกัน ภายในเหตุการณ์การส่งแบบฟอร์ม ฉันโหลดรูปภาพที่เลือกลงใน Asp.Net Web API
เครื่องมือ: รหัส VS, Visual Studio, SSMS, บุรุษไปรษณีย์
ลูกค้า: Reactjs
API: Asp.Net Core WebAPI
ตัวควบคุมนี้เชื่อมต่อกับการเชื่อมต่อฐานข้อมูลและจัดเตรียมวิธีการแสดงรายการ แทรก อัปเดต และลบบันทึกของพนักงานโดยจัดการคำขอ HTTP GET, POST, PUT และ DELETE
ตัวควบคุมนี้ทำงานโดยการโต้ตอบกับแบบฟอร์มพนักงานซึ่งพนักงานสามารถอัปโหลดรูปภาพของตนได้ แบบฟอร์มนี้ได้รับการออกแบบในฝั่ง React และสร้างขึ้นโดยใช้คำสั่ง npx create-react-app ในไดเร็กทอรีรากของโปรเจ็กต์
มีวิธีการที่เกี่ยวข้องสำหรับการดำเนินการ GET, POST, PUT และ DELETE ด้วยคำขอ GET บันทึกของพนักงานที่มีอยู่ทั้งหมดจะถูกแสดงรายการ คำขอ PUT จะอัปเดตบันทึกพนักงานที่ระบุ และยังใช้เพื่อเปลี่ยนรูปโปรไฟล์ของพนักงานด้วย คำขอ POST จะเพิ่มบันทึกพนักงานใหม่และอัปโหลดรูปโปรไฟล์ของพนักงาน คำขอ DELETE จะลบบันทึกพนักงานที่ระบุ
นอกจากนี้ ยังมีวิธีพิเศษสองวิธี ได้แก่ SaveImage() และ DeleteImage() สำหรับการโหลดและการลบรูปภาพในบันทึกของพนักงาน วิธีการเหล่านี้จัดการการอัพโหลดและการลบภาพโปรไฟล์พนักงาน
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 EmployeeRegisterAPI . Models ; using System . IO ; using Microsoft . AspNetCore . Hosting ; namespace EmployeeRegisterAPI . Controllers { [ Route ( "api/[controller]" ) ] [ ApiController ] public class EmployeeController : ControllerBase { private readonly EmployeeDbContext _context ; private readonly IWebHostEnvironment _hostEnvironment ; public EmployeeController ( EmployeeDbContext context , IWebHostEnvironment hostEnvironment ) { _context = context ; this . _hostEnvironment = hostEnvironment ; } // GET: api/EmployeeModels [ HttpGet ] public async Task < ActionResult < IEnumerable < EmployeeModel > > > GetEmployees ( ) { return await _context . Employees . Select ( x => new EmployeeModel ( ) { EmployeeID = x . EmployeeID , EmployeeName = x . EmployeeName , Occupation = x . Occupation , ImageName = x . ImageName , ImageSrc = String . Format ( "{0}://{1}{2}/Images/{3}" , Request . Scheme , Request . Host , Request . PathBase , x . ImageName ) } ) . ToListAsync ( ) ; } // GET: api/Employee/5 [ HttpGet ( "{id}" ) ] public async Task < ActionResult < EmployeeModel > > GetEmployeeModel ( int id ) { var employeeModel = await _context . Employees . FindAsync ( id ) ; if ( employeeModel == null ) { return NotFound ( ) ; } return employeeModel ; } // PUT: api/Employee/5 // To protect from overposting attacks, enable the specific properties you want to bind to, for // more details, see https://go.microsoft.com/fwlink/?linkid=2123754. [ HttpPut ( "{id}" ) ] public async Task < IActionResult > PutEmployeeModel ( int id , [ FromForm ] EmployeeModel employeeModel ) { if ( id != employeeModel . EmployeeID ) { return BadRequest ( ) ; } if ( employeeModel . ImageFile != null ) { DeleteImage ( employeeModel . ImageName ) ; employeeModel . ImageName = await SaveImage ( employeeModel . ImageFile ) ; } _context . Entry ( employeeModel ) . State = EntityState . Modified ; try { await _context . SaveChangesAsync ( ) ; } catch ( DbUpdateConcurrencyException ) { if ( ! EmployeeModelExists ( id ) ) { return NotFound ( ) ; } else { throw ; } } return NoContent ( ) ; } // POST: api/Employee // To protect from overposting attacks, enable the specific properties you want to bind to, for // more details, see https://go.microsoft.com/fwlink/?linkid=2123754. [ HttpPost ] public async Task < ActionResult < EmployeeModel > > PostEmployeeModel ( [ FromForm ] EmployeeModel employeeModel ) { employeeModel . ImageName = await SaveImage ( employeeModel . ImageFile ) ; _context . Employees . Add ( employeeModel ) ; await _context . SaveChangesAsync ( ) ; return StatusCode ( 201 ) ; } // DELETE: api/Employee/5 [ HttpDelete ( "{id}" ) ] public async Task < ActionResult < EmployeeModel > > DeleteEmployeeModel ( int id ) { var employeeModel = await _context . Employees . FindAsync ( id ) ; if ( employeeModel == null ) { return NotFound ( ) ; } DeleteImage ( employeeModel . ImageName ) ; _context . Employees . Remove ( employeeModel ) ; await _context . SaveChangesAsync ( ) ; return employeeModel ; } private bool EmployeeModelExists ( int id ) { return _context . Employees . Any ( e => e . EmployeeID == id ) ; } [ NonAction ] public async Task < string > SaveImage ( IFormFile imageFile ) { string imageName = new String ( Path . GetFileNameWithoutExtension ( imageFile . FileName ) . Take ( 10 ) . ToArray ( ) ) . Replace ( ' ' , '-' ) ; imageName = imageName + DateTime . Now . ToString ( "yymmssfff" ) + Path . GetExtension ( imageFile . FileName ) ; var imagePath = Path . Combine ( _hostEnvironment . ContentRootPath , "Images" , imageName ) ; using ( var fileStream = new FileStream ( imagePath , FileMode . Create ) ) { await imageFile . CopyToAsync ( fileStream ) ; } return imageName ; } [ NonAction ] public void DeleteImage ( string imageName ) { var imagePath = Path . Combine ( _hostEnvironment . ContentRootPath , "Images" , imageName ) ; if ( System . IO . File . Exists ( imagePath ) ) System . IO . File . Delete ( imagePath ) ; } } }
แบบฟอร์มนี้อนุญาตให้ผู้ใช้เพิ่มหรือแก้ไขพนักงานได้ ส่วนประกอบจะมีแบบฟอร์มที่คุณสามารถอัปโหลดรูปภาพและป้อนข้อมูลเกี่ยวกับชื่อพนักงานและงานได้ แบบฟอร์มประกอบด้วยพื้นที่อัพโหลดรูปภาพและช่องป้อนข้อความสองช่อง
มีการใช้ตัวแปรจำนวนมาก ตัวแปร defaultImageSrc เก็บเส้นทางรูปภาพเริ่มต้น ตัวแปร InitialFieldValues ประกอบด้วยค่าเริ่มต้นที่จะใช้ในสถานะเริ่มต้นของส่วนประกอบ การใช้ useState สถานะของค่าจะถูกติดตามภายในส่วนประกอบ
ฟังก์ชัน useEffect ถูกใช้ในระหว่างการโหลดส่วนประกอบ และเมื่อตัวแปร recordForEdit เปลี่ยนแปลง จะกระตุ้นให้ส่วนประกอบถูกโหลดซ้ำ และตัวแปรค่าจะได้รับการอัปเดตด้วยฟังก์ชัน setValues
ฟังก์ชัน handleInputChange จะถูกเรียกเมื่อช่องป้อนข้อความมีการเปลี่ยนแปลง ฟังก์ชันนี้จะบันทึกชื่อและค่าของฟิลด์ที่เปลี่ยนแปลงโดยใช้ e.target.name และ e.target.value และอัปเดตตัวแปรค่าโดยใช้ฟังก์ชัน setValues
ฟังก์ชัน showPreview จะถูกเรียกหากพื้นที่อัพโหลดรูปภาพมีการเปลี่ยนแปลง ฟังก์ชันนี้จะบันทึกเส้นทางของไฟล์ที่เลือกไว้ในตัวแปร imageFile และสร้างการแสดงตัวอย่างไฟล์โดยใช้ออบเจ็กต์ FileReader และอัปเดตตัวแปร imageSrc
ฟังก์ชั่นตรวจสอบความถูกต้องของแบบฟอร์ม ฟังก์ชันนี้ใช้เพื่อให้แน่ใจว่ามีการเติมตัวแปรค่าอย่างเหมาะสม ฟังก์ชัน setErrors จะอัปเดตตัวแปรข้อผิดพลาด และฟังก์ชัน resetForm จะรีเซ็ตแบบฟอร์มและล้างตัวแปรข้อผิดพลาด
ฟังก์ชัน handleFormSubmit จะถูกเรียกเมื่อมีการส่งแบบฟอร์ม ฟังก์ชันนี้จะดึงข้อมูลแบบฟอร์มโดยใช้วัตถุ FormData และส่งข้อมูลไปยังเซิร์ฟเวอร์โดยการเรียกใช้ฟังก์ชัน addOrEdit
ฟังก์ชัน ApplyErrorClass จะใช้คลาสฟิลด์ที่ไม่ถูกต้องกับฟิลด์ที่ไม่ถูกต้อง ส่งผลให้ฟิลด์เหล่านี้แสดงข้อผิดพลาด
ส่วนประกอบจะมีแบบฟอร์มที่คุณสามารถอัปโหลดรูปภาพและป้อนข้อมูลเกี่ยวกับชื่อพนักงานและงานได้ แบบฟอร์มประกอบด้วยพื้นที่อัพโหลดรูปภาพและช่องป้อนข้อความสองช่อง
import React , { useState , useEffect } from 'react'
const defaultImageSrc = '/img/3135715.png'
const initialFieldValues = {
employeeID : 0 ,
employeeName : '' ,
occupation : '' ,
imageName : '' ,
imageSrc : defaultImageSrc ,
imageFile : null
}
export default function Employee ( props ) {
const { addOrEdit , recordForEdit } = props
const [ values , setValues ] = useState ( initialFieldValues )
const [ errors , setErrors ] = useState ( { } )
useEffect ( ( ) => {
if ( recordForEdit != null )
setValues ( recordForEdit ) ;
} , [ recordForEdit ] )
const handleInputChange = e => {
const { name , value } = e . target ;
setValues ( {
... values ,
[ name ] : value
} )
}
const showPreview = e => {
if ( e . target . files && e . target . files [ 0 ] ) {
let imageFile = e . target . files [ 0 ] ;
const reader = new FileReader ( ) ;
reader . onload = x => {
setValues ( {
... values ,
imageFile ,
imageSrc : x . target . result
} )
}
reader . readAsDataURL ( imageFile )
}
else {
setValues ( {
... values ,
imageFile : null ,
imageSrc : defaultImageSrc
} )
}
}
const validate = ( ) => {
let temp = { }
temp . employeeName = values . employeeName == "" ? false : true ;
temp . imageSrc = values . imageSrc == defaultImageSrc ? false : true ;
setErrors ( temp )
return Object . values ( temp ) . every ( x => x == true )
}
const resetForm = ( ) => {
setValues ( initialFieldValues )
document . getElementById ( 'image-uploader' ) . value = null ;
setErrors ( { } )
}
const handleFormSubmit = e => {
e . preventDefault ( )
if ( validate ( ) ) {
const formData = new FormData ( )
formData . append ( 'employeeID' , values . employeeID )
formData . append ( 'employeeName' , values . employeeName )
formData . append ( 'occupation' , values . occupation )
formData . append ( 'imageName' , values . imageName )
formData . append ( 'imageFile' , values . imageFile )
addOrEdit ( formData , resetForm )
}
}
const applyErrorClass = field => ( ( field in errors && errors [ field ] == false ) ? ' invalid-field' : '' )
return (
< >
< div className = "container text-center" >
< p className = "lead" > p >
div >
< form autoComplete = "off" noValidate onSubmit = { handleFormSubmit } >
< div className = "card" style = { { backgroundColor : '#ced114' } } >
< img src = { values . imageSrc } className = "card-img-top" />
< div className = "card-body" >
< div className = "form-group" >
< input type = "file" accept = "image/*" className = { "form-control-file" + applyErrorClass ( 'imageSrc' ) }
onChange = { showPreview } id = "image-uploader" />
div >
< div className = "form-group" style = { { backgroundColor : '#ced114' } } >
< input className = { "form-control" + applyErrorClass ( 'employeeName' ) } placeholder = "Employee Name" name = "employeeName"
value = { values . employeeName }
onChange = { handleInputChange } />
div >
< div className = "form-group" >
< input className = "form-control" placeholder = "Occupation" name = "occupation"
value = { values . occupation }
onChange = { handleInputChange } />
div >
< div className = "form-group text-center" >
< button type = "submit" className = "btn btn-light" style = { { color : '#ced114' } } > Submit button >
div >
div >
div >
form >
>
)
}
ส่วนประกอบ React นี้จัดการการสร้าง แก้ไข การลบ และการดูบันทึกพนักงาน
มันใช้ตะขอ useState และ useEffect React useState กำหนดตัวแปรสถานะสำหรับสถานะของส่วนประกอบและส่งกลับ setState useEffect รันฟังก์ชันเพื่อตอบสนองต่อเหตุการณ์ต่างๆ เช่น การโหลดหรือการวาดส่วนประกอบใหม่
Axios ใช้เพื่อทำการเรียกบริการเว็บ RESTful ฟังก์ชันตัวช่วยที่เรียกว่า EmployeeAPI จะสร้างอินสแตนซ์การโทร RESTful และสามารถเปลี่ยน URL ทรัพยากรได้โดยใช้ฟีเจอร์ของ Axios
ฟังก์ชัน RefreshEmployeeList ดึงบันทึกพนักงานจากเซิร์ฟเวอร์และตั้งค่าเป็นสถานะของส่วนประกอบด้วย setEmployeeList
ฟังก์ชัน addOrEdit จัดการการสร้างหรืออัปเดตบันทึกพนักงาน วัตถุ FormData มีรายการผู้ใช้สำหรับบันทึกพนักงาน
ฟังก์ชัน onDelete จะขอให้ผู้ใช้ยืนยันว่าต้องการลบบันทึกหรือไม่ จากนั้นจึงส่งคำขอ DELETE ไปยังเซิร์ฟเวอร์
ฟังก์ชั่น imageCard ใช้เพื่อแสดงบัตรพนักงาน การ์ดประกอบด้วยรูปภาพของพนักงาน ชื่อ รายละเอียดงาน และปุ่มลบ
สุดท้าย ส่วนประกอบจะประกอบด้วยส่วนหัวของจัมโบตรอน แบบฟอร์มพนักงาน และตารางบัตรพนักงาน ตารางจะแสดงบัตรพนักงานที่มีสามคอลัมน์และแถวเพิ่มเติมโดยที่คอลัมน์ที่สามไม่ว่าง
{imageCard(employeeList[3 * i])} | {employeeList[3 * i + 1] ? imageCard(employeeList[3 * i + 1]) : null} | {employeeList[3 * i + 2] ? imageCard(employeeList[3 * i + 2]) : null} |
import React , { useState , useEffect } from 'react'
import Employee from './Employee'
import axios from "axios" ;
export default function EmployeeList ( ) {
const [ employeeList , setEmployeeList ] = useState ( [ ] )
const [ recordForEdit , setRecordForEdit ] = useState ( null )
useEffect ( ( ) => {
refreshEmployeeList ( ) ;
} , [ ] )
const employeeAPI = ( url = 'https://localhost:44334/api/Employee/' ) => {
return {
fetchAll : ( ) => axios . get ( url ) ,
create : newRecord => axios . post ( url , newRecord ) ,
update : ( id , updatedRecord ) => axios . put ( url + id , updatedRecord ) ,
delete : id => axios . delete ( url + id )
}
}
function refreshEmployeeList ( ) {
employeeAPI ( ) . fetchAll ( )
. then ( res => {
setEmployeeList ( res . data )
} )
. catch ( err => console . log ( err ) )
}
const addOrEdit = ( formData , onSuccess ) => {
if ( formData . get ( 'employeeID' ) == "0" )
employeeAPI ( ) . create ( formData )
. then ( res => {
onSuccess ( ) ;
refreshEmployeeList ( ) ;
} )
. catch ( err => console . log ( err ) )
else
employeeAPI ( ) . update ( formData . get ( 'employeeID' ) , formData )
. then ( res => {
onSuccess ( ) ;
refreshEmployeeList ( ) ;
} )
. catch ( err => console . log ( err ) )
}
const showRecordDetails = data => {
setRecordForEdit ( data )
}
const onDelete = ( e , id ) => {
e . stopPropagation ( ) ;
if ( window . confirm ( 'Are you sure to delete this record?' ) )
employeeAPI ( ) . delete ( id )
. then ( res => refreshEmployeeList ( ) )
. catch ( err => console . log ( err ) )
}
const imageCard = data => (
< div className = "card" onClick = { ( ) => { showRecordDetails ( data ) } } >
< img src = { data . imageSrc } className = "card-img-top rounded-circle" />
< div className = "card-body" >
< h5 > { data . employeeName } h5 >
< span > { data . occupation } span > < br />
< button className = "btn btn-light delete-button" onClick = { e => onDelete ( e , parseInt ( data . employeeID ) ) } >
< i className = "far fa-trash-alt" > i >
button >
div >
div >
)
return (
< div className = "row" >
< div className = "col-md-12" style = { { backgroundColor : '#ced114' } } >
< div className = "jumbotron jumbotron-fluid py-4" style = { { backgroundColor : '#ced114' } } >
< div className = "container text-center" style = { { backgroundColor : '#ced114' } } >
< h1 className = "display-4" style = { { backgroundColor : '#ced114' , color : 'yellow' } } > Employee Register h1 >
div >
div >
div >
< div className = "container text-center" >
< p className = "lead" > p >
div >
< div className = "col-md-4" >
< Employee
addOrEdit = { addOrEdit }
recordForEdit = { recordForEdit }
/>
div >
< div className = "col-md-8" >
< table >
< tbody >
{
//tr > 3 td
[ ... Array ( Math . ceil ( employeeList . length / 3 ) ) ] . map ( ( e , i ) =>
< tr key = { i } >
< td > { imageCard ( employeeList [ 3 * i ] ) } td >
< td > { employeeList [ 3 * i + 1 ] ? imageCard ( employeeList [ 3 * i + 1 ] ) : null } td >
< td > { employeeList [ 3 * i + 2 ] ? imageCard ( employeeList [ 3 * i + 2 ] ) : null } td >
tr >
)
}
tbody >
table >
div >
div >
)
}
ฉันใช้ .Net Core 6.0 ในโปรเจ็กต์ของฉัน แพ็คเกจ Nuget ที่ต้องดาวน์โหลดในโครงการมีดังต่อไปนี้
Microsoft.VisualStudio.Web.CodeGeneration.Design
PM > NuGet I nstall-Package Microsoft.VisualStudio.Web.CodeGeneration.Design -Version 6.0.13
Microsoft.EntityFrameworkCore
PM > NuGet I nstall-Package Microsoft.EntityFrameworkCore -Version 7.0.4
Microsoft.EntityFrameworkCore.SqlServer
PM > NuGet I nstall-Package Microsoft.EntityFrameworkCore.SqlServer -Version 7.0.4
Microsoft.EntityFrameworkCore.เครื่องมือ
PM > NuGet I nstall-Package Microsoft.EntityFrameworkCore.Tools -Version 7.0.4
Microsoft.AspNetCore.Cors
PM > NuGet I nstall-Package Microsoft.AspNetCore.Cors -Version 2.2.0
ก่อนอื่น เรามาเพิ่มคลาสให้กับโฟลเดอร์ Models ของเรากันก่อน ฉันตั้งชื่อมันว่า EmployeeModel
public class EmployeeModel
{
[ Key ]
public int EmployeeID { get ; set ; }
[ Column ( TypeName = "nvarchar(50)" ) ]
public string EmployeeName { get ; set ; }
[ Column ( TypeName = "nvarchar(50)" ) ]
public string Occupation { get ; set ; }
[ Column ( TypeName = "nvarchar(100)" ) ]
public string ImageName { get ; set ; }
}
มาสร้างคลาสบริบทในโฟลเดอร์ Models ของเรากันดีกว่า
using Microsoft . EntityFrameworkCore ;
namespace EmployeeRegisterAPI . Models
{
public class EmployeeDbContext : DbContext //burada ef Dbcontext den kalitim aldirdik
{
public EmployeeDbContext ( DbContextOptions < EmployeeDbContext > options ) : base ( options )
{
}
public DbSet < EmployeeModel > Employees { get ; set ; }
}
}
ไปที่โฟลเดอร์ Startup.cs และสร้างสตริงการเชื่อมต่อสำหรับวิธี ConfigureServices
public void ConfigureServices ( IServiceCollection services )
{
services . AddControllers ( ) ;
//Baglanti dizesini olusturduk ve bu kodda sql server icin bir ConnectionString olusturduk "DevConnection" diye bunula baglanti bilgilerimizi appsettings de belirtecegiz
services . AddDbContext < EmployeeDbContext > ( options => options . UseSqlServer ( Configuration . GetConnectionString ( "DevConnection" ) ) ) ;
}
มาที่ appsettings.json กัน ที่นี่เราเขียนข้อมูลการเชื่อมต่อลงในไฟล์ json แบบนี้
"Logging" : {
"LogLevel" : {
"Default" : "Information" ,
"Microsoft" : "Warning" ,
"Microsoft.Hosting.Lifetime" : "Information"
}
} ,
"AllowedHosts" : "*" ,
//buradan sonraki kod satirlaridir
"ConnectionStrings" : {
"DevConnection" : "Server=LAPTOP-6OAEM3JA; Database=EmployeeDB; Trusted_Connection=True; MultipleActiveResultSets=True;"
}
}
หลังจากนั้น เราสร้างโปรเจ็กต์ของเรา ไปที่ตัวจัดการแพ็คเกจ และดำเนินการย้ายข้อมูล
PM > Add-Migration " InitialCreate "
มาสร้าง Migration ด้วยคำสั่งและสร้างโปรเจ็กต์ของเรากันดีกว่า
PM > update-database
จากนั้นเรามาตรวจสอบว่าฐานข้อมูลถูกสร้างขึ้นจาก MSSQL หรือไม่
จากนั้นเรามาสร้างคอนโทรลเลอร์สำหรับโมเดลของเรากันดีกว่า ฉันจะใช้ API Controller พร้อมการดำเนินการโดยใช้คอนโทรลเลอร์ EF
รูปภาพจะมาที่นี่ 2 รูป
เราสร้างการควบคุมของเรา ระบุโมเดลและไฟล์บริบทของเรา และระบุชื่อคอนโทรลเลอร์ของเรา
5 บริการเหล่านี้เรียกว่า AddDb.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("DevConnection"))); ฟังก์ชั่นจะสร้างคำขอสำหรับตัวควบคุมพนักงานนี้ทุกครั้งที่เราส่งคำขอไปยัง EmployeeController นี้ ตัวสร้างของ EmployeeController เป็นแบบสาธารณะ EmployeeController (บริบท EmployeeDbContext) ค่า EmployeeDbContext ในโค้ดนี้คือวิธีการฉีดการพึ่งพา asp.net นี้ ซึ่งได้รับการจัดการโดยอัตโนมัติโดยเฟรมเวิร์กเอง ดังนั้นคำขอในคอนโทรลเลอร์นี้จะสื่อสารกับ db ในตอนนี้
ตอนนี้ มาออกแบบฝั่งไคลเอ็นต์เพื่อให้โต้ตอบกับแบบฟอร์มพนักงานเพื่ออัปโหลดรูปภาพโปรไฟล์พนักงาน มาสร้างแอปโต้ตอบในไดเร็กทอรีโปรเจ็กต์ เราจำเป็นต้องเปิดพรอมต์คำสั่งจากไดเร็กทอรีของโปรเจ็กต์นี้
npx create-react-app employee-register-client
คำสั่ง Oxios ที่จะใช้สำหรับฝั่งไคลเอ็นต์
$ npm install react-axios
เราได้สร้างโครงสร้างของโครงการของเราแล้ว จากนี้ไป ฉันต้องการให้คุณตรวจสอบรหัสของฉันใน repo ของฉัน ขอให้โชคดี :)
GET /api/Employee
พารามิเตอร์ | ยา | คำอธิบาย |
---|---|---|
api_key | string | จำเป็น . รหัส API ของคุณ |
GET /api/Employee/${id}
พารามิเตอร์ | ยา | คำอธิบาย |
---|---|---|
id | string | จำเป็น . ค่าคีย์ของรายการที่จะเรียก |
{ "employeeID" : 3 , "employeeName" : " piedhorse " , "occupation" : " C# " , "imageName" : " capture_20231646962.jpeg " , "imageFile" : null , "imageSrc" : " https://localhost:44334/Images/capture_20231646962.jpeg " }