ASP.NET Web API 最佳實踐專案整合 - 內建篇
在 ASP.NET Web API 2 基礎下,建立整合完備的應用程式專案範本。
- 整合套件或自行開發來提供
RESTFul API 最佳實踐
中的建議功能。 - 配合
開發規範
提供一致有效率的開發方式及程式品質。
這篇介紹 ASP.NET Web API 對 RESTFul best practice 最佳實踐的支援。
相關套件
- HelpPage
網址樣式
一) 利用 RouteConfig 做樣式設定。
二) 利用 ASP.NET Web API 提供的 RoutePrefix 和 Route attribute,可在 Controller 及 Action 上指定。
Route = RoutePrefix() + Route(),Route 和 Prefix 相同也要加上 Route() 才會生效。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23// Controller
[RoutePrefix("api/values")]
public class ValuesController : ApiController
// GET api/values
[Route()]
public IEnumerable<string> Get()
// GET api/values/{id}, id 限定類型
[Route("{id:int}")]
public string Get(int id)
// POST api/values
[Route()]
public void Post([FromBody]string value)
// PUT api/values/{id}
[Route("{id:int}")]
public void Put(int id, [FromBody]string value)
// DELETE api/values/{id}
[Route("{id:int}")]
public void Delete(int id)
API 文件
ASP.NET Web API 自帶有 HelpPage 套件,可自動產生並直接在網站中提供 API 文件。
HelpPage 套件
新建專案時選擇 Web API 專案,就已包含 HelpPage 套件。
加入現有專案
套件:Install-Package Microsoft.AspNet.WebApi.HelpPage
完成後專案中會新增文件功能區域 Areas/HelpPage
並掛上 /Help
網址供叫用。
檢查 Global.asax,確保 Application_Start 有啟用 Area 功能:1
2
3
4
5
6protected void Application_Start()
{
// Add this code, if not present.
AreaRegistration.RegisterAllAreas();
// ...
}
啟用 XML 註解
HelpPage 預設沒有啟用 XML 格式的註解,需要手動調整啟用它。
編輯 Areas/HelpPage/App_Start/HelpPageConfig.cs,開放(反註解)以下內容:1
2config.SetDocumentationProvider(new XmlDocumentationProvider(
HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml")));
打開專案屬性設定,到 建置
修改 輸出
區段內容
啟用 XML 文件檔案:
[V] XML 文件檔案(X): [App_Data/XmlDocument.xml]
結果處理
OData 是 Web 資料存取的協定,提供一致的資料查詢及處理功能,ASP.NET Web API 支援 OData v3 和 v4 版本。
OData 相關官方文件:OData in ASP.NET Web API
在未啟用 OData 的情況下,可利用 LINQ 簡單實作出 filtering, sorting & searching 的功能。
更新或新增返回異動資訊
ASP.NET Web API 有 ApiController.Created() 方法提供狀態 201 及 Location Header 的回應。1
2
3responseMessage.Headers.Location = new Uri("https://api.shop.com/v1/products/123");
return Created("https://api.shop.com/v1/products/123", postData);
JSON 格式
ASP.NET Web API 預設是依據瀏覽器端送出的 Accept 標頭自動決定回應的內容格式。
修改 Global.asax 中 Application_Start() 關閉 XML 格式:1
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
認證
配合 OpenID Connect Provider and OAuth 2.0 Authorization Server,如 IdentityServer。
認證失敗,必須回傳 401 Unauthorized statue code。
ASP.NET Web API 有 ApiController.Unauthorized 方法提供狀態 401 回應。1
return Unauthorized();
或1
throw new HttpResponseException(HttpStatusCode.Unauthorized);
錯誤訊息
ASP.NET Web API 2 提供 HttpError
類別做為 Response 錯誤訊息的容器。
一般錯誤訊息的內容:1
2
3
4
5
6new HttpError("this is a error message.");
>>> Response >>>
{
"message": "this is a error message."
}
傳遞 Exception 的內容:1
2
3
4
5
6
7
8
9new HttpError(new InvalidOperationException(), true);
>>> Response >>>
{
"message": "發生錯誤。",
"exception_message": "由於該物件目前的狀態,導致作業無效。",
"exception_type": "System.InvalidOperationException",
"stack_trace": null
}
不夠用,可客製 Error 類別,如下例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class ErrorContent
{
public string Message { get; set; }
public string Description { get; set; }
public string Code { get; set; }
public List<Error> Errors { get; set; }
}
public class Error
{
public string Item { get; set; }
public string Message { get; set; }
public string Code { get; set; }
}
用法:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public async Task<IHttpActionResult> Get()
{
var err = new ErrorContent { Message = "error message" };
err.Errors = new List<Error> { new Error { Code = "1", Item = "123" } };
return ResponseMessage(Request.CreateResponse(HttpStatusCode.NotFound, err));
}
>>> Response >>>
{
"message": "error message",
"description": null,
"code": null,
"errors": [
{
"item": "123",
"message": null,
"code": "1"
}
]
}
要讓 null 欄位不回傳,調整 WebApiConfig.cs
加上1
config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
HTTP 狀態碼
Web API 2 提供 2 種定義好狀態碼的 Response 方式。
一)常用狀態,ApiController 提供 Result Creator method,如下例:
- Ok() // 200
- Unauthorized() // 401
- BadRequest() // 400
- NotFound() // 404
- InternalServerError() // 500
1 | public async Task<IHttpActionResult> Get() |
二)HttpStatusCode 列舉 (官方文件中有完整表列)1
2
3
4
5public async Task<IHttpActionResult> Get()
{
var member = new Member { Num = 1, Name = "John" };
return ResponseMessage(Request.CreateResponse(HttpStatusCode.OK, member));
}
若是錯誤,可以用以下方法更明確,會轉為 status code 回傳1
throw new HttpResponseException(HttpStatusCode.NotImplemented);