基於IHttpHandler 的非標準webapi
基於IHttpHandler 的非標準webapi
此篇文章是本菜鳥對於公司大神自研框架的研究,也就是扒程式碼…
如有不足請指出
先舉個栗子,在名稱空間ABC.WebSiteAPI下有SystemUserAPIAPI類,類中有Create這個方法
namespace ABC.WebSiteAPI { public class SystemUserAPI { public static void Create(string name) { //balabala } } }
想要做到通過這個連結可以響應上述方法
http://localhost/API/SystemUser/Create?name=xxx
1.web.config中定義handlers,可以路由到對應的程式集和類
而這個類就是繼承IHttpHandler的自定義handel,入口
<system.webServer> <handlers> <add name="WebSiteAPI" verb="*" path="/API/*" type="ABC.APIHandle,ABC"/> </handlers> </system.webServer>
2.所有介面都寫在同一個程式集下,本例就是ABC.WebSiteAPI,初始化時載入該程式集下的所有類(Assembly類的多種靜態Load方法載入程式集),例如SystemUserAPI…,存入字典項
3.入口handle類中,獲取響應的httpcontext,獲得請求的類名,方法名,引數
4.驗證之前初始化的字典項中是否存在請求的類名(在類名中找是否存在SystemUserAPI)
找到對應的類名,即可獲得類下的所有方法
驗證請求的方法名是否在上述所有方法中(查詢是否存在Create)
5.引數
找到對應的方法後,可以通過MethodInfo.GetParameters()獲取引數(這裡是方法本身的引數,而不是請求的引數)
迴圈引數,驗證對應的請求中是否合法(如非空,型別不匹配之類的)並封裝成object陣列。記得要轉換成對應的型別用Convert.ChangeType,部分程式碼如下
private object GetParmValueFromRequest(ParameterInfo parm)
{
var parmValue = Context.Request[parm.Name];
var parmType = parm.ParameterType;
if (parmType == typeof(string)) return parmValue;
if (string.IsNullOrEmpty(parmValue)) // 如引數未定義,返回null
{
if (parmType.IsGenericType && parmType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
return null; // 判斷引數型別是否為Nullable
}
try
{
if (parmType.IsPrimitive) // 如引數為基元型別,進行型別轉換
return Convert.ChangeType(parmValue, parmType);
if (parmType == typeof(Guid)) return Guid.Parse(parmValue);
if (parmType == typeof(DateTime)) return DateTime.Parse(parmValue);
return Json.Deserialize(parmValue, parmType); // 如果引數為自定義物件,根據字串反序列化出物件,該方法是自己封裝的
}
catch (Exception ex)
{
return null;
}
}
6.呼叫方法
方法.Invoke(例項, 引數);
就可以啦
以上就是根據程式碼自己所總結的步驟和思路啦
應用場景,頻繁的與移動端做互動,MVC顯的太過臃腫,那目前webapi又沒有與mvc做分割,所以用IHttpHandler結合反射,做的一個輕量的框架