1. 程式人生 > >基於IHttpHandler 的非標準webapi

基於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結合反射,做的一個輕量的框架