iT邦幫忙

2025 iThome 鐵人賽

DAY 8
0

哈囉大家好!
今天要練習如何用Controller來發送POST request~
這次練習用的API是{JSON Placeholder},
JSONPlaceholder提供免費的REST API, 提供模擬資料來測試GET, POST, PUT, PATCH DELETE等HTTP method。

根據官方文檔,其中有個endpoint -> https://jsonplaceholder.tyicode.com/posts 可以模擬使用者發佈一篇新貼文的情境,傳遞的body格式如下:

title: 'exampleTitle',
body: 'Hello World! This is my first post,
userId: 7

模擬使用者上傳貼文後返回的資料格式如下:

id: 101,
title: 'exampleTitle',
body: 'Hello World! This is my first post',
userId: 7

1. 建立Angular前端簡易介面

接下來把過程寫成實際的程式碼!
開始寫後端之前,先用Angular架一個簡單的前端頁面,讓我可以輸入貼文的標題和內容:

<h1>上傳貼文</h1>
<h4>標題</h4>
<input type="text" [(ngModel)]="title" />
<h4>內容</h4>
<input type="text" [(ngModel)]="body" />
<button (click)="createPost()">上傳貼文</button>

在ts檔中處理發送POST request的function:

createPost() {
    const newPost = {
      title: this.title,
      body: this.body,
      userId: 1, // 假設 userId 是 1
    };

    const endpoint = 'http://localhost:5232/post/updatePost';
    this.http.post(endpoint, newPost).subscribe({
      next: (response) => {
        console.log(response);
      },
      error: (err) => {
        console.log(err);
      },
    });
  }

2. 後端建立Post Controller

再來要處理後端~
在Client.cs檔中新增PostClient class, 並且定義回傳格式PostResponse class:

public class PostClient
{
    public class PostResponse
    {
        public int? id { get; set; }
        public string? title { get; set; }
        public string? body { get; set; }
        public int? userId { get; set; }
    }
    
    public static async Task<PostResponse?> CreatePostAsync(Post post)
    {
        using (HttpClient client = new HttpClient())
        {
            try
            {
                var jsonContent = JsonSerializer.Serialize(post);
                var content = new StringContent(jsonContent, System.Text.Encoding.UTF8, "application/json");

                var response = await client.PostAsync("https://jsonplaceholder.typicode.com/posts", content);
                response.EnsureSuccessStatusCode();

                var jsonResponse = await response.Content.ReadAsStringAsync();
                var postResponse = JsonSerializer.Deserialize<PostResponse>(jsonResponse);

                return postResponse;
            }
            catch (HttpRequestException)
            {
                return null;
            }
        }
    }
}

接著在Controllers資料夾中建立PostController.cs檔(撰寫格式和GET request大同小異):

using Microsoft.AspNetCore.Mvc;


public class Post
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Body { get; set; }
    public int UserId { get; set; }
}

[ApiController]
[Route("[controller]")]
public class PostController : ControllerBase
{
    [HttpPost("updatePost")]
    public async Task<IActionResult> CreatePost([FromBody] Post post)
    {
        var response = await PostClient.CreatePostAsync(post);
        if (response is not null)
        {
            return CreatedAtAction(nameof(CreatePost), new { id = response.id }, response);
        }
        return null;
    }
}

這裡比較特別的是,因為Angular的來源是http://localhost:4200, 後端API的來源是http://localhost:5235, 瀏覽器的同源政策下會讓程式碼報錯。所以要在後端開放CORS(跨來源資源共享):

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy("Frontend", // 指定名稱為Frontend
        policy =>
        {
            policy.WithOrigins("http://localhost:4200") // 帶入Angular來源
                  .AllowAnyHeader()
                  .AllowAnyMethod();
        });
});

builder.Services.AddControllers();

var app = builder.Build();

app.UseCors("Frontend");

app.MapControllers();

app.Run();

在前端填入測試內容,按下上傳按鈕後,打開瀏覽器dev tool,就可以看到後端回傳的資料了!

總結

  1. 學習利用controller發送POST request
  2. 針對不同來源的前後端,開放跨來源資源共享(CORS)

目前對於基本的API操作有了一些認識,明天要來看看什麼是「資料傳輸物件(DTO)」~


上一篇
DAY 7 - 用Controller 發送GET request
下一篇
DAY 9 - 使用 Model 定義資料結構與 Migration 編輯資料庫
系列文
30天的旅程!從學習C#到開發小專案9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言