簡介
Api作為業務邏輯提供方,承載了專案的核心邏輯,因而具有相對高的邏輯複雜性。在這樣的前提下如何簡化程式碼編寫,如何規範統一書寫風格和邏輯規範,如何提升程式碼的維護性和擴展性。專案的搭建的高內聚低耦合變得重要。
範例的是企業級項目,框架圖如下
#api層.jpg
Security:重寫了Http請求(Override DelegatingHandler),在請求的切面進行合法性判斷,順便進行簽名要求的預處理。
Client:定義了統一的介面呼叫方式共呼叫端使用,簡化及統一了介面使用。
Ctrl層:作為服務的直接提供方,在伺服器上直接提供類似RestFul風格的介面(感覺嚴格的RestFul風格,需要有完整的領域模型##驅動# ,實際上的情況總是不盡人意,領域抽象能力不夠。層:作為業務模型層,提供業務邏輯的實際操作。使用統一的實體模型,並聯絡Ibatis上,進行資料操作。 具體的程式碼結構如下圖:
Api-UML.jpg
以下是各個模組的詳細介紹和程式碼範例:
Entity library專案程式碼範例
專案架構如下圖:
##entity.jpg#Domain模組,作為實體模型,簡易程式碼如下
public class User { public int Id { get; set; } public string NickName { get; set; } public string Avatar { get; set; } }Request,請求結構模型,利用了泛型接口,將請求類別和返回類別聯繫,起到了控制倒轉的作用。
public abstract class AbstractRequest { public bool ValidateParameters() { //公用方法示例,验证参数合法性 } } public interface IRequest<t> where T:AbstractResponse { //获取接口名称 string GetApiName(); //获取接口编码 string GetApiCode(); } //获取User信息的请求结构定义 public class GetUserRequest:AbstractRequest,IRequest<getuserresponse> { public int Id { get; set; } public string GetApiName() { return "User.GetUserDetail"; } public string GetApiCode() { return "User001"; } }</getuserresponse></t>Response模組,作為請求的回傳類型,定義統一的回傳結構,以便於消費者進行一致性回傳碼判斷處理。
public abstract class AbstractResponse { //返回码 public int Code { get; set; } //报错信息 public string Message { get; set; } } public class GetUserResponse:AbstractResponse { public User User { get; set; } }Service專案程式碼範例專案結構如下圖: service.jpg程式碼範例:
public interface IUserService { GetUserResponse GetUser(int id); } public class BaseService { //protected SqlInstance sqlInstance; public BaseService() { //sqlInstance=new SqlInstance(); //实例化数据库连接 //... } //... } public class UserService:BaseService,IUserService { public GetUserResponse GetUser(int id) { //链接数据库获取数据 //... throw new NotImplementedException(); } }

類別庫程式碼範例類別庫只是處理了
安全性
性問題,在api請求入口處新增上權限判斷。使用重寫Http請求的方式。程式碼範例public class MyHandler : DelegatingHandler
{
protected async override Task<httpresponsemessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
IEnumerable<string> keyEnumerable;
var t1 = request.Headers.TryGetValues("key", out keyEnumerable);
var key = keyEnumerable.FirstOrDefault();
if (!true)//验证类似于token的权限
{
return await Task.Factory.StartNew<httpresponsemessage>(
() => new HttpResponseMessage(HttpStatusCode.Forbidden)
{
Content = new StringContent("error message")
});
}
//如果有signature,判断,并加结果标志,没有的话,清除signature相关信息,防止伪造。
//.....
return await base.SendAsync(request, cancellationToken);
}
}</httpresponsemessage></string></httpresponsemessage>
抽象化出來的權限判斷,可直接呼叫到webapi端,加入到
路由作為介面的實際定義,webapi定義了介面檔案的實際規則,並做出對應的安全管理及介面的權限控制。學習微信的權限控制,大概確定了幾種介面:
這些權限的判斷都會放在了Security做了集中管理。介面定義只需要在對應的邏輯上使用判斷合法性即可。 程式碼範例:
public class UserController : ApiController { private IUserService userService; public UserController() { userService=new UserService(); } [Signature]//安全签名过滤器判断 [HttpPost] public GetUserResponse GetUser(GetUserRequest request) { //参数判断,安全性判断等等 var ret = userService.GetUser(request.Id); return ret; } }以上是一個獲取用戶資訊的範例接口,而作為接口入口的路由配置,則需要對請求的合法性進行判斷,路由配置碼如下:
public static void Register(HttpConfiguration config) { // Web API configuration and services // Configure Web API to use only bearer token authentication. config.SuppressDefaultHostAuthentication(); config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{action}", defaults: new { id = RouteParameter.Optional } ); //添加的代码,添加http请求的入口处理 config.MessageHandlers.Add(new MyHandler()); }Client類別庫程式碼範例
Client類別庫定義了介面呼叫的公共方法。
1、利用泛型接口,將請求類別和返回類別進行了封裝,簡化調用的程式碼書寫。
3、消費者的呼叫都同意使用統一類別庫,是的日誌的處理統一,傳回的錯誤也可以一致化定義。
程式碼範例如下: public interface IClient
{
T Execute<t>(IRequest<t> request) where T : AbstractResponse;
}
public class DefaultClient:IClient
{
private readonly string appKey;
private readonly string appSecret;
private readonly string baseUrl = "http://localhost:16469/api/";
private readonly bool isNeedLogFile = false;
private readonly LogFile logFile;
public static readonly string SecureHeaderAppKey = "secure_head_appkey";
public static readonly string SecureHeaderSignature = "secure_head_signature";
public DefaultClient()
{
baseUrl = ConfigurationManager.AppSettings["service_base_url"];
appKey = ConfigurationManager.AppSettings["app_key"];
appSecret = ConfigurationManager.AppSettings["app_secret"];
isNeedLogFile = "1".Equals(ConfigurationManager.AppSettings["client_log_file"]);
logFile = new LogFile("client_log_path");
logFile.SubPath = appKey;
}
public DefaultClient(string serviceBase, string code, string key)
{
baseUrl = serviceBase;
appKey = code;
appSecret = key;
}
public T Execute<t>(IRequest<t> request) where T : AbstractResponse
{
var webRequest = (HttpWebRequest)WebRequest.Create(baseUrl + request.GetApiName());
webRequest.Method = "POST";
string reqJson;
string sign;
using (Stream rs = webRequest.GetRequestStream())
{
reqJson = JsonConvert.SerializeObject(request);
byte[] reqBytes = Encoding.UTF8.GetBytes(reqJson);
rs.Write(reqBytes, 0, reqBytes.Length);
rs.Close();
}
webRequest.ContentType = "application/json";
webRequest.Headers.Add(SecureHeaderAppKey, appKey);
sign = ComputeHash(appKey, appSecret, reqJson);
webRequest.Headers.Add(SecureHeaderSignature, sign);
//记录日志
if (isNeedLogFile)
{
logFile.Log(string.Format("[{0}] 请求内容: {1}", request.GetApiCode(), reqJson));
logFile.Log(string.Format("[{0}] 请求签名: {1}", request.GetApiCode(), sign));
}
try
{
using (var resp = (HttpWebResponse)webRequest.GetResponse())
{
try
{
Stream respStream = resp.GetResponseStream();
if (respStream == null)
{
throw new WebException("GetResponseStream returned null");
}
var streamReader = new StreamReader(respStream);
string respStr = streamReader.ReadToEnd();
//记录日志
if (isNeedLogFile)
{
logFile.Log(string.Format("[{0}] 响应内容: {1}", request.GetApiCode(), respStr));
}
return JsonConvert.DeserializeObject<t>(respStr);
}
catch (Exception e)
{
//记录日志
if (isNeedLogFile)
{
logFile.Log(string.Format("[{0}] 响应错误: {1}", request.GetApiCode(), e.Message));
}
throw new ApplicationException(e.Message, e);
}
}
}
catch (WebException e)
{
var errMsg = new StreamReader(e.Response.GetResponseStream()).ReadToEnd();
//记录日志
if (isNeedLogFile)
{
logFile.Log(string.Format("[{0}] 请求错误: {1}", request.GetApiCode(), errMsg));
}
throw new APIServiceException(errMsg);
}
}
private string ComputeHash(string key, string secret, string body)
{
return
Convert.ToBase64String(
SHA1.Create().ComputeHash(Encoding.Default.GetBytes(string.Concat(key, secret, body.Trim()))));
}
}</t></t></t></t></t>
以上就是Api项目端的各个核心环节的详细介绍。
接下来会对调用端即前端进行简单的介绍。Asp.net(三)Web端展示
以上是Asp.net(二)業務處理介面專案(Web Api)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

C#和.NET提供了強大的功能和高效的開發環境。 1)C#是一種現代、面向對象的編程語言,結合了C 的強大和Java的簡潔性。 2).NET框架是一個用於構建和運行應用程序的平台,支持多種編程語言。 3)C#中的類和對像是面向對象編程的核心,類定義數據和行為,對像是類的實例。 4).NET的垃圾回收機制自動管理內存,簡化開發者的工作。 5)C#和.NET提供了強大的文件操作功能,支持同步和異步編程。 6)常見錯誤可以通過調試器、日誌記錄和異常處理來解決。 7)性能優化和最佳實踐包括使用StringBuild

.NETFramework是一個跨語言、跨平台的開發平台,提供一致的編程模型和強大的運行時環境。 1)它由CLR和FCL組成,CLR管理內存和線程,FCL提供預構建功能。 2)使用示例包括讀取文件和LINQ查詢。 3)常見錯誤涉及未處理異常和內存洩漏,需使用調試工具解決。 4)性能優化可通過異步編程和緩存實現,保持代碼可讀性和可維護性是關鍵。

C#.NET保持持久吸引力的原因包括其出色的性能、豐富的生態系統、強大的社區支持和跨平台開發能力。 1)性能表現優異,適用於企業級應用和遊戲開發;2).NET框架提供了廣泛的類庫和工具,支持多種開發領域;3)擁有活躍的開發者社區和豐富的學習資源;4).NETCore實現了跨平台開發,擴展了應用場景。

C#.NET中的設計模式包括Singleton模式和依賴注入。 1.Singleton模式確保類只有一個實例,適用於需要全局訪問點的場景,但需注意線程安全和濫用問題。 2.依賴注入通過注入依賴提高代碼靈活性和可測試性,常用於構造函數注入,但需避免過度使用導致複雜度增加。

C#.NET在現代世界中廣泛應用於遊戲開發、金融服務、物聯網和雲計算等領域。 1)在遊戲開發中,通過Unity引擎使用C#進行編程。 2)金融服務領域,C#.NET用於開發高性能的交易系統和數據分析工具。 3)物聯網和雲計算方面,C#.NET通過Azure服務提供支持,開發設備控制邏輯和數據處理。

C#.NET開發者社區提供了豐富的資源和支持,包括:1.微軟的官方文檔,2.社區論壇如StackOverflow和Reddit,3.GitHub上的開源項目,這些資源幫助開發者從基礎學習到高級應用,提升編程技能。

C#.NET的優勢包括:1)語言特性,如異步編程簡化了開發;2)性能與可靠性,通過JIT編譯和垃圾回收機制提升效率;3)跨平台支持,.NETCore擴展了應用場景;4)實際應用廣泛,從Web到桌面和遊戲開發都有出色表現。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。