ASP.NET Core — สร้าง API สำหรับอัพโหลดไฟล์พร้อม Metadata (F#)

ใน ASP.NET Core เราสามารถเขียน API สำหรับอัพโหลดไฟล์แบบง่าย ๆ ผ่าน HttpPost โดยใช้ IFormFile

ในกรณีที่ต้องการดึง JSON Metadata ที่แนบพร้อมกับไฟล์ ต้อง Extract ข้อมูลจาก Request Form แล้ว Deserialize ออกเป็น Object ที่ต้องการ

ตัวอย่างนี้เป็น API สำหรับอัพโหลดไฟล์ ซึ่งสามารถดึงข้อมูล Metadata พร้อมกับเขียนไฟล์ลง Temp

  1. ประกาศ Type Metadata และ UploadResult สำหรับแลกเปลี่ยนข้อมูลระหว่าง Client — Server
type Metadata { A : string }
type UploadResult { Success: bool; Message: string }

2. ประกาศฟังก์ชั่น getMetadata() สำหรับดึง Metadata ออกจาก HttpReqeust และ writeFile() สำหรับเขียนไฟล์ที่ลง Temp

let getMetadata<T>(request: HttpRequest) =
let success, jsonValue = request.Form.TryGetValue("json")
if success then
let json = String.Join("", jsonValue)
let obj = JsonConvert.DeserializeObject<T>(json)
Some obj
else
None
let writeFile (file: IFormFile) =
let guid = Guid.NewGuid().ToString("N")
let name = sprintf "%s-%s" guid file.Name
let tempPath = Path.Combine(Path.GetTempPath(), name)
use stream =
new FileStream(tempPath, FileMode.Create, FileAccess.Write)
file.CopyTo(stream)
(tempPath)

3. เขียน Controller โดยประกาศฟังก์ชั่นสำหรับรับไฟล์คือ UploadFile() โดยต้องระบุ ฟังก์ชั่น Attribute เป็น HttpPost

[<HttpPost>]
member this.UploadFile() =
let request = this.Request
let files = request.Form.Files
  if files.Length == 0 then 
{ Success: false; Message = "Invalid request" }
else
match getMetadata<Metadata>(request) with
| Some info ->
let file = files.[0]
writeFile(file) |> ignore
{ Success = true; Message = "" }
| None ->
{ Success = false; Message = "Invalid request" }

4. ทดสอบอัพโหลดไฟล์จาก Client โดยใช้ HttpClient

let uploadFile() =
let file = "Resource/UnsignedPdf.pdf";
let api = "http://localhost:5000/upload/uploadFile"
let json = """
{ "A": "A" }
"""
let form = new MultipartFormDataContent()
let content = File.ReadAllBytes(file)
form.Add(new ByteArrayContent(content), "files", "Hello.pdf")
form.Add(new StringContent(json,
Encoding.UTF8, "application/json"), "json")
use client = new HttpClient()
  async {
let! result = client.PostAsync(api, form) |> Async.WaitTask
let! content =
result.Content.ReadAsStringAsync() |> Async.WaitTask
printfn "%A" content
} |> Async.RunSynchronously
Like what you read? Give wk a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.