最近都把專案升級成 .Net  6 ,沒啥大問題,只是最近想找個機會好好研究一下 Web API,想說遇到或是測試到就筆記一下,所以也不是啥教學文
如果有啥更好得做法,可以在跟我說,這邊沒有啥難度的技術,可能對很多高手來說就是喝水一樣的事情。

           
這次案例設計很簡單就是一個 <form> 我直接 POST 到 Web API (案例中為 TestController) 上面 
介紹一下 <form> 的結構
   
  
    
    
        <form action="/api/test/sample2" method="post">
            <div style="margin-bottom:20px">
                <legend>用戶帳號</legend><br />
                <input class="input" type="text" placeholder="donma" name="userId">
            </div>
            <fieldset>
                <legend>選擇你的興趣:</legend>
                <div>
                    <input type="checkbox" name="hobby" checked value="釣魚">
                    <label>釣魚</label>
                </div>
                <div>
                    <input type="checkbox" name="hobby" checked value="睡覺">
                    <label>睡覺</label>
                </div>
                <div>
                    <input type="checkbox" name="hobby" value="看電影">
                    <label>看電影</label>
                </div>
                <div>
                    <input type="checkbox" name="hobby" value="上網">
                    <label>上網</label>
                </div>
            </fieldset>
            <div>
                <legend for="gender">性別</legend><br>
                <select name="gender">
                    <option value="0">Female</option>
                    <option value="1">Male</option>
                </select>
            </div>
            <div>
                <legend for="">生日</legend><br>
                <input class="input" type="date" placeholder="2022-10-11" value="2022-10-11" name="userBirth">
            </div>
            <div>
                <legend for="">薪水</legend><br>
                <input class="input" type="number" value="199.99" name="userSalary">
            </div>
            <hr />
            <div>
                <input type="submit" value="送出">
            </div>
        </form>
    
  
出來長相大概長這樣,如果你看 code 無法想像的話

接下來就是 首先在 .Net 6 中,你得先在 Program.cs 加入 app.MapControllers();  這一步我常常忘記

    
Web API Code Sample2 :
    
    
  
    
    using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Dynamic;
namespace TestWebAPI1.API
{
    [Route("api/test")]
    [ApiController]
    public class TestController : ControllerBase
    {
        [HttpGet]
        public string Get()
        {
            return "Test Service";
        }
        [HttpPost]
        [Route("sample2")]
        public IActionResult RegistUserActionResult([FromForm] string userId,
                                                    [FromForm] string gender,
                                                    [FromForm] string[] hobby,
                                                    [FromForm] DateTimeOffset userBirth,
                                                    [FromForm] decimal? userSalary)
        {
            dynamic res = new ExpandoObject();
            res.UserId = userId;
            res.Gender = gender;
            res.Hobby = hobby;
            res.Birth = userBirth;
            res.Salary = userSalary;
        
            return Ok(res);
        }
    }
}
    
    
  
    這案例很簡單回傳就是 IActionResult ,其實回傳他預設就會是 ontent-type: application/json; charset=utf-8
回應結果
  
  
    
    {"UserId":"許當麻","Gender":"0","Hobby":["釣魚","睡覺"],"Birth":"2022-10-11T00:00:00+08:00","Salary":199.99}
  
看一下回應的 headers
這裡面值得一提的就是,input 如果 type  是 number ,WebAPI 這邊是可以用 decimal 承接,如果是 input:checkbox 同一個 name ,則可以使用
    string[]  接 (如文中的 hobby)
這其實非常方便,當然一般狀況通常都是在前端準備好物件(一個 自訂好結構的 json
    ) 在一次往後送,不過這是測試,我也非常偷懶的直接用 dynamic 接了就拋
再來測試 XML 輸出,因為輸出 dynamic 比較麻煩所以我建立了一個物件 User.cs 
   
  
    
    
    public class User
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string[]? Hobby { get; set; }
        public string Gender { get; set; }
        public decimal? Salary { get; set; }
        public DateTimeOffset Birth { get; set; }
    }
    
    
    
  
Web API Code Sample3 :
    
  
    
    
    
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Dynamic;
namespace TestWebAPI1.API
{
    [Route("api/test")]
    [ApiController]
    public class TestController : ControllerBase
    {
        [HttpGet]
        public string Get()
        {
            return "Test Service";
        }
        [HttpPost]
        [Route("sample3")]
        //輸出為 XML
        [Produces("application/xml")]
        public IActionResult RegistUserJson([FromForm] string userId,
                                     [FromForm] string gender,
                                     [FromForm] string[] hobby,
                                       [FromForm] DateTimeOffset userBirth,
                                       [FromForm] decimal? userSalary)
        {
            var u = new Models.User();
            u.Name = userId;
            u.Id = userId;
            u.Gender = gender;
            u.Birth = userBirth;
            u.Hobby = hobby;
            u.Salary = userSalary;
            return Ok(u);
        }
    }
}
    
    
  
    注意,需要再 Program.cs 中 var app = builder.Build();  之前加入  
   
  
    builder.Services.AddControllers().AddXmlSerializerFormatters().AddXmlDataContractSerializerFormatters();
  
當然 form 那邊的 action 也要改成  action="/api/test/sample3" 
回應結果:
    
  
    
<?xml version="1.0" encoding="UTF-8"?>
<User xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <script />
   <Id>許當麻</Id>
   <Name>許當麻</Name>
   <Hobby>
      <string>釣魚</string>
      <string>睡覺</string>
   </Hobby>
   <Gender>0</Gender>
   <Salary>199.99</Salary>
   <Birth>2022-10-11T00:00:00+08:00</Birth>
</User>
    
    
    
  
回應的 headers 

    注意: 如果你的 Web API 部分有些是允許 null 或是空值傳入 ,但是你傳入到 Web API 會出現  
{
   "type":"https://tools.ietf.org/html/rfc7231#section-6.5.1",
   "title":"One or more validation errors occurred.",
   "status":400,
   "traceId":"00-c483917b91ff3410d2305af939c2ac3e-60280f3f85d80a58-00",
   "errors":{
      "userId":[
         "The userId field is required."
      ]
   }
需要再 Program.cs 中 修改這一段 
   
  
    
    //for not check required
	builder.Services.AddControllers(options => options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true);
    
  
需要再 AddControllers 中加入  options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true  
大概筆記到這裡,不算教學,算是給自己的筆記