private void Register(HttpOptions config, Type controllerType, object controller, string rooturl, HttpApiServer server, ControllerAttribute ca, Action <EventActionRegistingArgs> callback) { DataConvertAttribute controllerDataConvert = controllerType.GetCustomAttribute <DataConvertAttribute>(false); OptionsAttribute controllerOptionsAttribute = controllerType.GetCustomAttribute <OptionsAttribute>(false); if (string.IsNullOrEmpty(rooturl)) { rooturl = "/"; } else { if (rooturl[0] != '/') { rooturl = "/" + rooturl; } if (rooturl[rooturl.Length - 1] != '/') { rooturl += "/"; } } RequestMaxRPS control_maxRPS = controllerType.GetCustomAttribute <RequestMaxRPS>(); List <FilterAttribute> filters = new List <FilterAttribute>(); if (!ca.SkipPublicFilter) { filters.AddRange(config.Filters); } IEnumerable <FilterAttribute> fas = controllerType.GetCustomAttributes <FilterAttribute>(false); filters.AddRange(fas); IEnumerable <SkipFilterAttribute> skipfilters = controllerType.GetCustomAttributes <SkipFilterAttribute>(false); foreach (SkipFilterAttribute item in skipfilters) { RemoveFilter(filters, item.Types); } object obj = controller; if (obj is IController) { string path = System.IO.Path.GetDirectoryName(controllerType.Assembly.Location) + System.IO.Path.DirectorySeparatorChar; ((IController)obj).Init(server, path); server.Log(EventArgs.LogType.Info, $"init {controllerType} controller path {path}"); } foreach (MethodInfo mi in controllerType.GetMethods(BindingFlags.Instance | BindingFlags.Public)) { if (string.Compare("Equals", mi.Name, true) == 0 || string.Compare("GetHashCode", mi.Name, true) == 0 || string.Compare("GetType", mi.Name, true) == 0 || string.Compare("ToString", mi.Name, true) == 0 || mi.Name.IndexOf("set_") >= 0 || mi.Name.IndexOf("get_") >= 0) { continue; } if (mi.GetCustomAttribute <NotActionAttribute>(false) != null) { continue; } bool noconvert = false; RequestMaxRPS maxRPS = mi.GetCustomAttribute <RequestMaxRPS>(); if (maxRPS == null) { maxRPS = control_maxRPS; } DataConvertAttribute actionConvert = mi.GetCustomAttribute <DataConvertAttribute>(); OptionsAttribute methodOptionsAttribute = mi.GetCustomAttribute <OptionsAttribute>(); if (mi.GetCustomAttribute <NoDataConvertAttribute>(false) != null) { noconvert = true; actionConvert = null; } else { if (actionConvert == null) { actionConvert = controllerDataConvert; } } string sourceUrl = rooturl + mi.Name; string url = sourceUrl; string method = HttpParse.GET_TAG + "/" + HttpParse.POST_TAG; string route = null; GetAttribute get = mi.GetCustomAttribute <GetAttribute>(false); if (get != null) { method = HttpParse.GET_TAG; route = get.Route; } PostAttribute post = mi.GetCustomAttribute <PostAttribute>(false); if (post != null) { method = HttpParse.POST_TAG; route = post.Route; } DelAttribute del = mi.GetCustomAttribute <DelAttribute>(false); if (del != null) { method = HttpParse.DELETE_TAG; route = del.Route; } PutAttribute put = mi.GetCustomAttribute <PutAttribute>(false); if (put != null) { method = HttpParse.PUT_TAG; route = put.Route; } if (server.Options.UrlIgnoreCase) { url = sourceUrl.ToLower(); } RouteTemplateAttribute ra = null; if (!string.IsNullOrEmpty(route)) { ra = new RouteTemplateAttribute(route); string reurl; if (route[0] == '/') { reurl = ra.Analysis(null); } else if (route[0] == '{') { reurl = ra.Analysis(url + "/"); } else { reurl = ra.Analysis(route.IndexOf('/', 0) > 0 ? rooturl : url + "/"); } if (reurl == null) { if (route[0] == '/') { reurl = route; } else { reurl = rooturl + route; } } server.UrlRewrite.Add(null, reurl, url); } ActionHandler handler = GetAction(url); if (handler != null) { server.Log(EventArgs.LogType.Warring, "{0} already exists! replaced with {1}.{2}!", url, controllerType.Name, mi.Name); } handler = new ActionHandler(obj, mi, this.Server); if (mi.ReturnType == typeof(Task) || mi.ReturnType.BaseType == typeof(Task)) { handler.Async = true; PropertyInfo pi = mi.ReturnType.GetProperty("Result", BindingFlags.Public | BindingFlags.Instance); if (pi != null) { handler.PropertyHandler = new PropertyHandler(pi); } } handler.Path = rooturl; if (methodOptionsAttribute == null) { handler.OptionsAttribute = controllerOptionsAttribute; } else { handler.OptionsAttribute = methodOptionsAttribute; } if (handler.OptionsAttribute == null && !ca.SkipPublicFilter) { handler.OptionsAttribute = handler.HttpApiServer.Options.CrossDomain; } handler.NoConvert = noconvert; handler.SingleInstance = ca.SingleInstance; handler.DataConverter = actionConvert; handler.Route = ra; handler.Method = method; handler.SourceUrl = sourceUrl; handler.Filters.AddRange(filters); fas = mi.GetCustomAttributes <FilterAttribute>(false); handler.Filters.AddRange(fas); handler.Url = url; if (maxRPS != null) { handler.MaxRPS = maxRPS.Value; } int rpsSetting = server.Options.GetActionMaxrps(handler.SourceUrl); if (rpsSetting > 0) { handler.MaxRPS = rpsSetting; } skipfilters = mi.GetCustomAttributes <SkipFilterAttribute>(false); foreach (SkipFilterAttribute item in skipfilters) { RemoveFilter(handler.Filters, item.Types); } EventActionRegistingArgs registing = new EventActionRegistingArgs(); registing.Url = url; registing.Handler = handler; registing.Cancel = false; callback?.Invoke(registing); if (!registing.Cancel) { AddHandlers(url, handler); server.ActionSettings(handler); server.Log(EventArgs.LogType.Info, $"register { controllerType.Name}.{mi.Name} to [{handler.Method}:{url}]"); } else { server.Log(EventArgs.LogType.Info, $"register { controllerType.Name}.{mi.Name} cancel "); } } }