//----------------------------------------------------------- // 获取接口清单 //----------------------------------------------------------- // 获取接口清单 static TypeAPI GetTypeApi(Type type) { // 获取接口列表 var rootUrl = GetApiRootUrl(type); var typeapi = new TypeAPI(); var apis = new List <API>(); var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly); foreach (MethodInfo method in methods) { HttpApiAttribute attr = ReflectHelper.GetHttpApiAttribute(method); if (attr != null) { var api = new API() { Name = method.Name, Description = attr.Description, ReturnType = ParseDataType(attr.Type, method.ReturnType).ToString(), CacheDuration = attr.CacheSeconds, AuthIP = attr.AuthIP, AuthToken = attr.AuthToken, AuthLogin = attr.AuthLogin, AuthUsers = attr.AuthUsers, AuthRoles = attr.AuthRoles, AuthVerbs = attr.AuthVerbs.IsEmpty() ? "" : attr.AuthVerbs.ToUpper(), Status = attr.Status, Log = attr.Log, Remark = attr.Remark, Example = attr.Example, Url = GetMethodDisplayUrl(rootUrl, method), UrlTest = GetMethodTestUrl(rootUrl, method, attr.AuthToken), Params = GetMethodParams(method, attr.AuthToken), Method = method, RType = attr.Type }; apis.Add(api); } } // typeapi.Apis = apis.OrderBy(t => t.Name).ToList(); typeapi.Description = ReflectHelper.GetDescription(type); typeapi.Histories = ReflectHelper.GetHistories(type); return(typeapi); }
//---------------------------------------------- // 入口 //---------------------------------------------- /// <summary>处理 Web 方法调用请求</summary> public static void ProcessRequest(HttpContext context, object handler) { // 解析类型、方法、参数等信息 // 对于aspx页面,执行时编译出来的是类似ASP.xxx_aspx的类,这不是我们想要处理的类,追溯处理父类(IMPORTANT!) var decoder = RequestDecoder.CreateInstance(context); var args = decoder.ParseArguments(); var type = handler.GetType(); if (type.FullName.StartsWith("ASP.") && type.BaseType != null) { type = type.BaseType; } var methodName = decoder.MethodName; var method = ReflectHelper.GetMethod(type, methodName); var attr = ReflectHelper.GetHttpApiAttribute(method); // 处理预留方法 if (ProcessReservedMethod(context, type, methodName, args)) { return; } // 普通方法调用 try { // 检测方法可用性 // 获取需要的参数 CheckMethod(context, method, attr, args); var parameters = ReflectHelper.GetParameters(method, args); // 获取方法调用结果并依情况缓存 object result; if (attr.CacheSeconds == 0) { result = method.Invoke(handler, parameters); } else { var p = SerializeHelper.ToJson(parameters).ClearSpace().TrimStart('[').TrimEnd(']'); //.Replace("\"", ""); var cacheKey = string.Format("{0}-{1}-{2}", handler, method.Name, p); // 可考虑用 MD5 做缓存健名 var expireDt = DateTime.Now.AddSeconds(attr.CacheSeconds); // 强制刷新缓存 if (args.ContainsKey("_refresh")) { bool refresh = (args["_refresh"].ToString() == "true"); if (refresh) { CacheHelper.SetCachedObject <object>(cacheKey, expireDt, () => { return(method.Invoke(handler, parameters)); }); } } result = CacheHelper.GetCachedObject <object>(cacheKey, expireDt, () => { return(method.Invoke(handler, parameters)); }); } // 输出结果 ResponseType dataType = attr.Type; if (args.ContainsKey("_type")) { dataType = (ResponseType)Enum.Parse(typeof(ResponseType), args["_type"].ToString(), true); } if (dataType == ResponseType.Auto && result != null) { dataType = ParseDataType(result.GetType()); } var wrap = HttpApiConfig.Instance.Wrap ?? attr.Wrap; var wrapInfo = attr.WrapCondition; WriteResult(context, result, dataType, attr.MimeType, attr.FileName, attr.CacheSeconds, attr.CacheLocation, wrap, wrapInfo); } catch (Exception ex) { if (ex is HttpApiException) { var err = ex as HttpApiException; WriteError(context, err.Code, err.Message); } else { var info = (ex.InnerException != null) ? ex.InnerException.Message : ex.Message; WriteError(context, 400, info); } HttpApiConfig.Instance.DoException(method, ex); } finally { HttpApiConfig.Instance.DoEnd(context); } }