ASP.NET Framework WebAPI是一種強大的框架,用於構建基於HTTP協議的Web服務。它提供了一種簡單而靈活的方式來創建和發佈RESTful風格的API。通過使用WebAPI,開發人員可以輕鬆地將現有的應用程式或服務暴露為可訪問的Web API,從而實現數據的交互和共用。 ...
一、什麼是WebAPI?
1.1-什麼是WebAPI?
WebAPI是一種用開發系統介面、設備介面API的技術,基於Http協議,請求和返回格式預設是Json格式。比WCF簡單、更通用;比WebService更節省流量,更簡潔。
1.2-WebAPI的特點?
- Action方法直接返回對象,專註於數據
- 更符合Restful的風格
- 有利於獨立於IIS部署
- Action可以直接聲明為async
二、什麼是Restful?
2.1-傳統的Http介面怎麼設計?
2.2-Http設計之初"謂詞語義"?
- GET:查詢獲取
- POST:添加
- Put:修改
- Delete:刪除
2.3-Http設計之初"謂詞語義"帶來的好處是什麼?
- 為不同的請求做不同的許可權的控制;
- 不需要"Delete","AddNew"這樣的Action名字,根據請求的類型就可以判斷
- 返回報文的格式也確定,不用在約定返回狀態碼,充分利用Http狀態碼
- 有利於系統優化,瀏覽器可以自動緩存Get請求
- Get沒有副作用,是冪等的,可以重試。
註意:返回結果儘量根據Http狀態碼返回。
三、簡單的WebAPI(.NET Framework)
3.1-簡單WebAPI和是使用非同步方式調用
/// <summary>
/// 需要繼承自ApiController
/// </summary>
public class PersonController : ApiController
{
public string[] Get() {
return new string[] { "西瓜程式猿", "Albert" };
}
public string Get(int id) {
return $"Haha:" + id;
}
public string Get(string name) {
return name;
}
}
}
3.2-WebAPI的參數
3.3-WebAPI的返回值
/// <summary>
/// HttpResponseMessage類型
/// 返回報文頭、內容等等信息(控制相應的內容)
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("Test3")]
public HttpResponseMessage Test3() {
HttpResponseMessage msg = new HttpResponseMessage();
msg.Content =new StringContent( "報文體");
msg.Headers.Add("Haha", "這是請求頭體");
msg.StatusCode = System.Net.HttpStatusCode.OK;
msg.Headers.Age = TimeSpan.FromDays(3);
return msg;
}
3.4-通過自定義路由處理API多版本
3.5-通過ControllerSelector實現多版本(配置路由規則)
(1)創建2個版本控制器
(2)在【WebApiConfig】的Register中,添加1個路由規則,並替換IHttpControllerSelector
config.Routes.MapHttpRoute(
name: "DefaultApiV1",
routeTemplate: "api/v1/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
//添加一個路由規則
config.Routes.MapHttpRoute(
name: "DefaultApiV2",
routeTemplate: "api/v2/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
//替換
config.Services.Replace(typeof(IHttpControllerSelector), new VersionControllerSelector(config));
(3)VersionControllerSelector.cs代碼如下:
namespace Demo
{
/// <summary>
/// 用來控制API版本
/// 需要繼承自DefaultHttpControllerSelector
/// </summary>
public class VersionControllerSelector : DefaultHttpControllerSelector
{
private readonly HttpConfiguration _config;
private IDictionary<string, HttpControllerDescriptor> _ctlMapping;
public VersionControllerSelector(HttpConfiguration config) : base(config)
{
this._config = config;
}
public override IDictionary<string, HttpControllerDescriptor> GetControllerMapping()
{
Dictionary<string, HttpControllerDescriptor> dict = new Dictionary<string, HttpControllerDescriptor>();
//載入所有程式集,然後遍歷
foreach (var asm in _config.Services.GetAssembliesResolver().GetAssemblies())
{
//獲得程式集所有的類,並且該類不是抽象類,並且繼承自ApiController
var controllerTypes = asm.GetTypes().Where(u => u.IsAbstract == false && typeof(ApiController).IsAssignableFrom(u));
//遍歷並生成名字
foreach (var ctrlType in controllerTypes)
{
string ctrolTypeNS = ctrlType.Namespace;//獲取命名空間名稱
var match = Regex.Match(ctrolTypeNS, @"\.v(\d)");//獲得需要的名稱
if (!match.Success)
{
continue;
}
string verNum = match.Groups[1].Value;//拿到版本號1提取出來
string ctrlTypeName = ctrlType.Name;//拿到類名(PersonController)
//拿到匹配的類型
var matchController = Regex.Match(ctrlTypeName, @"^(.+)Controller$");
if (!matchController.Success)
{
continue;
}
string ctrlName = matchController.Groups[1].Value;//得到合法的PersonController
string key = ctrlName + "v" + verNum;
dict[key] = new HttpControllerDescriptor(_config, ctrlName,ctrlType);
}
}
_ctlMapping = dict;
return dict;
}
public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
//拿到controller
string controller =(string)request.GetRouteData().Values["controller"];
if (_ctlMapping == null) {
//調用之前的方法拿到,key/value
_ctlMapping = GetControllerMapping();
}
// /api/v1/person
var matchVer = Regex.Match(request.RequestUri.PathAndQuery, @"/v(\d+)/");
if (!matchVer.Success) {
//我處理不了,讓父類處理
return base.SelectController(request);
}
string verNum = matchVer.Groups[1].Value;//2
string key = controller + "v" + verNum;
if (_ctlMapping.ContainsKey(key))
{
return _ctlMapping[key];
}
else {
//我處理不了,讓父類處理
return base.SelectController(request);
}
}
}
}
3.6-WebAPI中Filter-簡單判斷是否授權
(1)新建一個類。
(2)類的代碼如下:
namespace Demo.Filter
{
public class MyAuthorFilter : IAuthorizationFilter
{
public bool AllowMultiple => true;
public async Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
{
IEnumerable<string> userNames;
if (!actionContext.Request.Headers.TryGetValues("UserName", out userNames)){
//返回未授權狀態碼
return new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
};
string userName = userNames.First();
if (userName == "admin")
{
return await continuation();
}
else {
//返回未授權狀態碼
return new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
}
}
}
}
(3)在【WebApiConfig.cs】的Register方法進行註冊自定義的Filter。
//註冊自己寫的Filter
config.Filters.Add(new MyAuthorFilter());
3.7-WebAPI的異常處理
系統錯誤:
業務錯誤:
3.8-介面的安全性問題
3.9-JWT介紹
3.10-介面安全傳輸
原文鏈接:https://www.cnblogs.com/kimiliucn/p/17607795.html