public async Task BeforeRequestAsyncTest() { var context = new TestActionContext( httpApi: null, httpApiConfig: new HttpApiConfig(), apiActionDescriptor: new ApiActionDescriptor(typeof(IMyApi).GetMethod("PostAsync"))); context.RequestMessage.RequestUri = new Uri("http://www.webapi.com/"); context.RequestMessage.Method = HttpMethod.Post; var attr = new HttpGetAttribute(); await attr.BeforeRequestAsync(context); Assert.True(context.RequestMessage.Method == HttpMethod.Get); var attr2 = new HttpGetAttribute("/login"); await attr2.BeforeRequestAsync(context); Assert.True(context.RequestMessage.Method == HttpMethod.Get); Assert.True(context.RequestMessage.RequestUri == new Uri("http://www.webapi.com/login")); var attr3 = new HttpGetAttribute("http://www.baidu.com"); await attr3.BeforeRequestAsync(context); Assert.True(context.RequestMessage.Method == HttpMethod.Get); Assert.True(context.RequestMessage.RequestUri == new Uri("http://www.baidu.com")); }
public async Task BeforeRequestAsyncTest() { var context = new ApiActionContext { RequestMessage = new HttpApiRequestMessage { RequestUri = new Uri("http://www.webapi.com/") }, ApiActionDescriptor = ApiDescriptorCache.GetApiActionDescriptor(typeof(IMyApi).GetMethod("PostAsync")) }; var attr = new HttpGetAttribute(); await attr.BeforeRequestAsync(context); Assert.True(context.RequestMessage.Method == HttpMethod.Get); var attr2 = new HttpGetAttribute("/login"); await attr2.BeforeRequestAsync(context); Assert.True(context.RequestMessage.Method == HttpMethod.Get); Assert.True(context.RequestMessage.RequestUri == new Uri("http://www.webapi.com/login")); var attr3 = new HttpGetAttribute("http://www.baidu.com"); await attr3.BeforeRequestAsync(context); Assert.True(context.RequestMessage.Method == HttpMethod.Get); Assert.True(context.RequestMessage.RequestUri == new Uri("http://www.baidu.com")); }
public async Task OnRequestAsyncTest() { var apiAction = new ApiActionDescriptor(typeof(ITestApi).GetMethod("PostAsync")); var context = new TestRequestContext(apiAction, string.Empty); context.HttpContext.RequestMessage.RequestUri = new Uri("http://www.webapi.com/"); context.HttpContext.RequestMessage.Method = HttpMethod.Post; var attr = new HttpGetAttribute(); await attr.OnRequestAsync(context); Assert.True(context.HttpContext.RequestMessage.Method == HttpMethod.Get); var attr2 = new HttpGetAttribute("/login"); await attr2.OnRequestAsync(context); Assert.True(context.HttpContext.RequestMessage.Method == HttpMethod.Get); Assert.True(context.HttpContext.RequestMessage.RequestUri == new Uri("http://www.webapi.com/login")); var attr3 = new HttpGetAttribute("http://www.baidu.com"); await attr3.OnRequestAsync(context); Assert.True(context.HttpContext.RequestMessage.Method == HttpMethod.Get); Assert.True(context.HttpContext.RequestMessage.RequestUri == new Uri("http://www.baidu.com")); }
public override void OnActionExecuting(ActionExecutingContext filterContext) { filterContext.HttpContext.Response.Write("1 、这是OnActionExecuting---输出的内容<br />"); //filterContext.HttpContext.Session //1.0 获取当前过滤器的方法是由哪个action方法触发的(获取actin名称) string actionName = filterContext.ActionDescriptor.ActionName; filterContext.HttpContext.Response.Write("actionName=" + actionName + "<br />"); //2.0 获取当前action所在的控制器名称 string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName; //3.0 判断当前action是否贴有[HttpGet]属性 bool isTrue = filterContext.ActionDescriptor.IsDefined(typeof(HttpGetAttribute), false); filterContext.HttpContext.Response.Write("IsDefined(typeof(HttpGetAttribute))=" + isTrue + "<br />"); //4.0 获取当前action方法上贴有的[HttpGet]的对象实例 object[] httpgets = filterContext.ActionDescriptor.GetCustomAttributes(typeof(HttpGetAttribute), false); if (httpgets != null && httpgets.Any()) { HttpGetAttribute intance = httpgets[0] as HttpGetAttribute; } //5.0 记录当前方法的实际参数,2014-8-5 16:35:20 控制器/方法,参数1=参数1值,参数2=参数2值 var dic = filterContext.ActionParameters; base.OnActionExecuting(filterContext); }
public void TestAttributeMethodWithParameter() { var service = serviceProvider.GetService <AttributesService>(); var method = service.GetType().GetMethod("MethodWithParameter"); var attributes = method.GetCustomAttributes(typeof(HttpGetAttribute), false); Assert.AreEqual(1, attributes.Length); HttpGetAttribute attribute = (HttpGetAttribute)attributes[0]; Assert.AreEqual("httpget", attribute.Template); }
/// <summary> /// Resolves any Mvc attributes on the method. /// </summary> /// <param name="methodBuilder">The method being built.</param> /// <param name="methodInfo">The method being called.</param> /// <returns>True if any resolved; otherwise false.</returns> public static bool ResolveMvcAttributes( this IMethodBuilder methodBuilder, MethodInfo methodInfo) { HttpGetAttribute getAttr = methodInfo.GetCustomAttribute <HttpGetAttribute>(true); if (getAttr != null) { methodBuilder.SetCustomAttribute(AttributeUtility.BuildAttribute <string, HttpGetAttribute>(getAttr.Template)); return(true); } HttpPostAttribute postAttr = methodInfo.GetCustomAttribute <HttpPostAttribute>(true); if (postAttr != null) { methodBuilder.SetCustomAttribute(AttributeUtility.BuildAttribute <string, HttpPostAttribute>(postAttr.Template)); return(true); } HttpPutAttribute putAttr = methodInfo.GetCustomAttribute <HttpPutAttribute>(true); if (putAttr != null) { methodBuilder.SetCustomAttribute(AttributeUtility.BuildAttribute <string, HttpPutAttribute>(putAttr.Template)); return(true); } HttpPatchAttribute patchAttr = methodInfo.GetCustomAttribute <HttpPatchAttribute>(true); if (patchAttr != null) { methodBuilder.SetCustomAttribute(AttributeUtility.BuildAttribute <string, HttpPatchAttribute>(patchAttr.Template)); return(true); } HttpDeleteAttribute deleteAttr = methodInfo.GetCustomAttribute <HttpDeleteAttribute>(true); if (deleteAttr != null) { methodBuilder.SetCustomAttribute(AttributeUtility.BuildAttribute <string, HttpDeleteAttribute>(deleteAttr.Template)); return(true); } return(false); }
public static void AssertHttpPostOnly <T>(this T controller, Expression <Action <T> > action) where T : Controller { Type type = controller.GetType(); MethodCallExpression body = action.Body as MethodCallExpression; MethodInfo actionMethod = body.Method; HttpPostAttribute postAttribute = actionMethod.GetCustomAttributes(typeof(HttpPostAttribute), false) .Cast <HttpPostAttribute>() .SingleOrDefault(); HttpGetAttribute getAttribute = actionMethod.GetCustomAttributes(typeof(HttpGetAttribute), false) .Cast <HttpGetAttribute>() .SingleOrDefault(); Assert.That(postAttribute != null && getAttribute == null, "{0}.{1} does not have [HttpPost] attribute", controller.GetType().Name, actionMethod.Name); }
public void InitTest() { var descriptor = new ApiActionDescriptor("http://api.dev/", typeof(IAubTestApi).GetMethod("PostAsync")); var attr1 = new HttpGetAttribute(); attr1.Init(descriptor); Assert.True(descriptor.Method == HttpMethod.Get); Assert.True(descriptor.Route == null); Assert.True(descriptor.Url == new Uri("http://api.dev")); var attr2 = new HttpGetAttribute("part-list"); attr2.Init(descriptor); Assert.True(descriptor.Method == HttpMethod.Get); Assert.True(descriptor.Route == "part-list"); Assert.True(descriptor.Url == new Uri("http://api.dev/part-list")); }
/// <summary> /// Defines the request type of a controller method /// </summary> /// <param name="controllerName"></param> /// <param name="methodName"></param> /// <param name="methodAttributes"></param> /// <returns></returns> public static (RequestType, object) GetRequestType(string controllerName, string methodName, object[] methodAttributes) { try { var httpGetAttrCount = methodAttributes.Count(x => x.GetType() == typeof(HttpGetAttribute)); var httpPostAttrCount = methodAttributes.Count(x => x.GetType() == typeof(HttpPostAttribute)); var httpPutAttrCount = methodAttributes.Count(x => x.GetType() == typeof(HttpPutAttribute)); var httpDeleteAttrCount = methodAttributes.Count(x => x.GetType() == typeof(HttpDeleteAttribute)); if ((httpGetAttrCount + httpPostAttrCount + httpPutAttrCount + httpDeleteAttrCount) > 1) { throw new Exception($"Weber controller Error: Controller: {controllerName} => Method: {methodName} => Cannot have more than one request type attribute"); } foreach (var attribute in methodAttributes) { if (HttpGetAttribute.IsHttpGet(attribute)) { return(RequestType.GET, attribute); } if (HttpPostAttribute.IsHttpPost(attribute)) { return(RequestType.POST, attribute); } if (HttpPutAttribute.IsHttpPut(attribute)) { return(RequestType.PUT, attribute); } if (HttpDeleteAttribute.IsHttpDelete(attribute)) { return(RequestType.DELETE, attribute); } } } catch (Exception e) { throw new Exception($"RequestTypeHelper GetRequestType Error: {e.Message}"); } return(RequestType.None, null); }
public ApiCacheMiddleware(RequestDelegate next) { _next = next; var assembly = Assembly.GetExecutingAssembly(); Type[] types = assembly.GetTypes(); Type[] apicontrollers = types.Where(type => type.GetCustomAttribute <ApiControllerAttribute>() != null).ToArray(); foreach (Type ctrl in apicontrollers) { MethodInfo[] controllerMethods = ctrl.GetMethods(); RouteAttribute apiRoute = ctrl.GetCustomAttribute <RouteAttribute>(); if (apiRoute == null) { throw new Exception($"{ctrl.Name} doesn't have a \"Route\" Attribute"); } string ctrRoute = apiRoute.Template; foreach (MethodInfo meth in controllerMethods) { ApiCacheAttribute apiCacheAttribute = meth.GetCustomAttribute <ApiCacheAttribute>(); if (apiCacheAttribute != null) { string route; HttpGetAttribute get = meth.GetCustomAttribute <HttpGetAttribute>(); if (get != null) { route = get.Template; string key = "/" + ctrRoute + "/" + route; if (this.ApiMap.ContainsKey(key)) { throw new Exception("Api Method Route Repeat Exception!"); } this.ApiMap.Add(key, apiCacheAttribute); } } } } }
public async Task <ActionResult> GetController() { List <xQuyen> lstQuyens = new List <xQuyen>(); Assembly asm = Assembly.GetExecutingAssembly(); var q1 = asm .GetExportedTypes() .Where(x => typeof(CustomController).IsAssignableFrom(x) && !x.Name.Equals(typeof(CustomController).Name)) .Select(x => new { Controller = x.Name, Methods = x.GetMethods().Where(y => y.DeclaringType.IsSubclassOf(typeof(CustomController)) && y.IsPublic && !y.IsStatic).ToList() }); var BaseController = q1 .Where(x => x.Controller.Equals(typeof(BaseController <>).Name)) .Select(x => new { Controller = x.Controller.ToLower().Replace("controller", string.Empty), Actions = x.Methods.Where(y => y.IsVirtual).Select(y => new { Action = y.Name.ToLower(), Attributes = y.GetCustomAttributes(false).ToList() }) }) .FirstOrDefault(); var Controllers = q1 .Where(x => !x.Controller.Equals(typeof(BaseController <>).Name)) .Select(x => new { Controller = x.Controller.ToLower().Replace("controller", string.Empty), Actions = x.Methods.Where(y => !y.IsVirtual).Select(y => new { Action = y.Name.ToLower(), Attributes = y.GetCustomAttributes(false).ToList() }) }); DateTime time = DateTime.Now; if (BaseController != null) { foreach (var action in BaseController.Actions) { xQuyen quyen = new xQuyen(); HttpGetAttribute attr_Get = (HttpGetAttribute)action.Attributes.FirstOrDefault(x => x.GetType() == typeof(HttpGetAttribute)); RouteAttribute attr_Route = (RouteAttribute)action.Attributes.FirstOrDefault(x => x.GetType() == typeof(RouteAttribute)); if (attr_Get != null && attr_Route != null) { quyen.Method = HttpVerbs.Get.ToString().ToLower(); quyen.Template = string.IsNullOrWhiteSpace(attr_Route.Template) ? string.Empty : attr_Route.Template.ToLower(); lstQuyens.Add(quyen); } else if (attr_Get != null && attr_Route == null) { quyen.Method = HttpVerbs.Get.ToString().ToLower(); lstQuyens.Add(quyen); } else if (attr_Get == null && attr_Route != null) { quyen.Method = HttpVerbs.Get.ToString().ToLower(); quyen.Template = string.IsNullOrWhiteSpace(attr_Route.Template) ? string.Empty : attr_Route.Template.ToLower(); lstQuyens.Add(quyen); } HttpPostAttribute attr_Post = (HttpPostAttribute)action.Attributes.FirstOrDefault(x => x.GetType() == typeof(HttpPostAttribute)); if (attr_Post != null) { quyen.Method = HttpVerbs.Post.ToString().ToLower(); lstQuyens.Add(quyen); } HttpPutAttribute attr_Put = (HttpPutAttribute)action.Attributes.FirstOrDefault(x => x.GetType() == typeof(HttpPutAttribute)); if (attr_Put != null) { quyen.Method = HttpVerbs.Put.ToString().ToLower(); lstQuyens.Add(quyen); } HttpDeleteAttribute attr_Delete = (HttpDeleteAttribute)action.Attributes.FirstOrDefault(x => x.GetType() == typeof(HttpDeleteAttribute)); if (attr_Delete != null) { quyen.Method = HttpVerbs.Delete.ToString().ToLower(); lstQuyens.Add(quyen); } quyen.KeyID = 0; quyen.NgayTao = time; quyen.Controller = BaseController.Controller; quyen.Action = action.Action; quyen.MacDinh = true; quyen.Path = string.Join("/", quyen.Controller, quyen.Action, quyen.Template).TrimEnd('/'); } } foreach (var controller in Controllers) { List <xQuyen> lstTemps = new List <xQuyen>(); foreach (var action in controller.Actions) { xQuyen f = new xQuyen(); HttpGetAttribute attr_Get = (HttpGetAttribute)action.Attributes.FirstOrDefault(x => x.GetType() == typeof(HttpGetAttribute)); if (attr_Get != null) { f.Method = HttpVerbs.Get.ToString().ToLower(); // f.Template = string.IsNullOrWhiteSpace(attr_Get.Template) ? string.Empty : attr_Get.Template.ToLower(); lstTemps.Add(f); } HttpPostAttribute attr_Post = (HttpPostAttribute)action.Attributes.FirstOrDefault(x => x.GetType() == typeof(HttpPostAttribute)); if (attr_Post != null) { f.Method = HttpVerbs.Post.ToString().ToLower(); //f.Template = string.IsNullOrWhiteSpace(attr_Post.Template) ? string.Empty : attr_Post.Template.ToLower(); lstTemps.Add(f); } HttpPutAttribute attr_Put = (HttpPutAttribute)action.Attributes.FirstOrDefault(x => x.GetType() == typeof(HttpPutAttribute)); if (attr_Put != null) { f.Method = HttpVerbs.Put.ToString().ToLower(); // f.Template = string.IsNullOrWhiteSpace(attr_Put.Template) ? string.Empty : attr_Put.Template.ToLower(); lstTemps.Add(f); } HttpDeleteAttribute attr_Delete = (HttpDeleteAttribute)action.Attributes.FirstOrDefault(x => x.GetType() == typeof(HttpDeleteAttribute)); if (attr_Delete != null) { f.Method = HttpVerbs.Delete.ToString().ToLower(); // f.Template = string.IsNullOrWhiteSpace(attr_Delete.Template) ? string.Empty : attr_Delete.Template.ToLower(); lstTemps.Add(f); } RouteAttribute attr_Route = (RouteAttribute)action.Attributes.FirstOrDefault(x => x.GetType() == typeof(RouteAttribute)); if (attr_Route != null) { f.Method = string.IsNullOrWhiteSpace(f.Method) ? HttpVerbs.Get.ToString().ToLower() : f.Method; f.Template = string.IsNullOrWhiteSpace(attr_Route.Template) ? string.Empty : attr_Route.Template.ToLower(); lstTemps.Add(f); } f.KeyID = 0; f.NgayTao = time; f.Controller = controller.Controller; f.Action = action.Action; f.Path = string.Join("/", f.Controller, f.Action, f.Template).TrimEnd('/'); } lstQuyens.AddRange(lstTemps); } return(await SaveData(lstQuyens.ToArray())); }
public void Apply(ActionModel action) { var method = action.ActionMethod; if (method.IsDefined(typeof(HttpMethodAttribute))) { return; } action.Selectors.Clear(); //custom prefix HttpMethodAttribute attr; foreach (var custom in _options.CustomRule) { if (action.ActionName.StartsWith(custom.Key)) { switch (custom.Value) { case HttpVerbs.HttpGet: attr = new HttpGetAttribute(action.ActionName); break; case HttpVerbs.HttpPost: attr = new HttpPostAttribute(action.ActionName); break; case HttpVerbs.HttpDelete: attr = new HttpDeleteAttribute(action.ActionName); break; case HttpVerbs.HttpPut: attr = new HttpPutAttribute(action.ActionName); break; default: attr = new HttpPostAttribute(action.ActionName); break; } ModelConventionHelper.AddRange(action.Selectors, ModelConventionHelper.CreateSelectors(new List <object> { attr })); return; } } if (method.Name.StartsWith("Get")) { attr = new HttpGetAttribute(method.Name); } else if (method.Name.StartsWith("Post") || method.Name.StartsWith("Add")) { attr = new HttpPostAttribute(method.Name); } else if (method.Name.StartsWith("Update") || method.Name.StartsWith("Put")) { attr = new HttpPutAttribute(method.Name); } else if (method.Name.StartsWith("Del") || method.Name.StartsWith("Delete")) { attr = new HttpDeleteAttribute(method.Name); } else { attr = new HttpPostAttribute(method.Name); } ModelConventionHelper.AddRange(action.Selectors, ModelConventionHelper.CreateSelectors(new List <object> { attr })); }
public IHttpBehavior Create(MethodInfo methodInfo, IConfig config) { if (methodInfo == null) { return(null); } var behavior = new HttpBehavior(config, methodInfo); var methodAttrs = methodInfo.GetCustomAttributes(false); var methodAttr = methodAttrs.FirstOrDefault(a => a is HttpMethodAttribute) as HttpMethodAttribute; if (methodAttr == null) { methodAttr = new HttpGetAttribute(); } behavior.Method = methodAttr.Method; var enctypeAttr = methodAttrs.FirstOrDefault(a => a is EnctypeAttribute) as EnctypeAttribute; if (enctypeAttr == null) { enctypeAttr = new FormUrlEncodedAttribute(); if (!behavior.FiexdHeaders.ContainsKey(Headers.ContentType)) { behavior.FiexdHeaders[Headers.ContentType] = enctypeAttr.ContentType; } } else { behavior.FiexdHeaders[Headers.ContentType] = enctypeAttr.ContentType; } var timeout = methodAttrs.FirstOrDefault(a => a is TimeoutAttribute) as TimeoutAttribute; if (timeout != null) { behavior.Timeout = timeout.Timeout; } var url = String.Empty; var urlAttr = methodAttrs.FirstOrDefault(a => a is UrlAttribute) as UrlAttribute; if (urlAttr != null && urlAttr.Url != null) { url = urlAttr.Url.Trim(); } var urlPathIndexs = new Dictionary <int, string>(); if (!String.IsNullOrEmpty(url)) { int index = 0; behavior.Url = _UrlPathRegex.Replace(url, new MatchEvaluator(match => { var r = index++; urlPathIndexs.Add(r, match.Groups[1].Value.ToLower().Trim()); return("{" + r + "}"); })); behavior.IsWithPath = behavior.Url != url; if (!behavior.Url.ToLower().StartsWith("http")) { if (!behavior.Url.StartsWith("/")) { behavior.Url = "/" + behavior.Url; } behavior.Url = config.Host + behavior.Url; } } else { behavior.Url = config.Host; } var parameters = methodInfo.GetParameters(); for (var i = 0; i < parameters.Length; i++) { var param = parameters[i]; var paramName = param.Name; var parmeterAttr = param.GetCustomAttributes(typeof(ParameterAttribute), false).FirstOrDefault() as ParameterAttribute; if (parmeterAttr == null || parmeterAttr is PathAttribute) { paramName = GetParmeterName(parmeterAttr) ?? paramName; if (behavior.IsWithPath && urlPathIndexs.Values.Contains(paramName)) { foreach (var pair in urlPathIndexs) { if (pair.Value == paramName) { behavior.PathKeys.Add(pair.Key, new HttpParameterBehavior(paramName, i, config.Encoding, config.Formatter)); } } continue; } else if (parmeterAttr == null) { parmeterAttr = new QueryAttribute(); } else { throw new Exception("url中没有定义对应的path:" + paramName); } } paramName = GetParmeterName(parmeterAttr) ?? paramName; var add = false; add = add || ParameterBehavior(behavior, paramName, parmeterAttr as HeaderAttribute, i, config.Encoding, config.Formatter); add = add || ParameterBehavior(behavior, paramName, parmeterAttr as FieldAttribute, enctypeAttr, i, config.Encoding, config.Formatter); add = add || ParameterBehavior(behavior, paramName, parmeterAttr as FieldMapAttribute, enctypeAttr, i, config.Encoding, config.Formatter); add = add || ParameterBehavior(behavior, paramName, parmeterAttr as PartAttribute, enctypeAttr, i, config.Encoding, config.Formatter); add = add || ParameterBehavior(behavior, paramName, parmeterAttr as QueryAttribute, enctypeAttr, i, config.Encoding, config.Formatter); add = add || ParameterBehavior(behavior, paramName, parmeterAttr as BodyAttribute, i); } behavior.Verify(); return(behavior); }
public async Task <IActionResult> GetController() { List <xFeature> lstFeatures = new List <xFeature>(); Assembly asm = Assembly.GetExecutingAssembly(); var Controllers = asm.GetExportedTypes() .Where(x => typeof(ControllerBase).IsAssignableFrom(x) && !x.Name.Equals(typeof(BaseController <>).Name)) .Select(x => new { Controller = x.Name, Methods = x.GetMethods().Where(y => y.DeclaringType.IsSubclassOf(typeof(ControllerBase)) && y.IsPublic && !y.IsStatic).ToList() }) .Select(x => new { Controller = x.Controller.ToLower().Replace("controller", string.Empty), Actions = x.Methods.Select(y => new { Action = y.Name.ToLower(), Attributes = y.GetCustomAttributes(true).ToList() }) }); DateTime time = DateTime.Now; foreach (var controller in Controllers) { List <xFeature> lstTemps = new List <xFeature>(); foreach (var action in controller.Actions) { xFeature f = new xFeature(); HttpGetAttribute attr_Get = (HttpGetAttribute)action.Attributes.FirstOrDefault(x => x.GetType() == typeof(HttpGetAttribute)); if (attr_Get != null) { f.Method = HttpMethods.Get.ToLower(); f.Template = string.IsNullOrWhiteSpace(attr_Get.Template) ? string.Empty : attr_Get.Template.ToLower(); lstTemps.Add(f); } HttpPostAttribute attr_Post = (HttpPostAttribute)action.Attributes.FirstOrDefault(x => x.GetType() == typeof(HttpPostAttribute)); if (attr_Post != null) { f.Method = HttpMethods.Post.ToLower(); f.Template = string.IsNullOrWhiteSpace(attr_Post.Template) ? string.Empty : attr_Post.Template.ToLower(); lstTemps.Add(f); } HttpPutAttribute attr_Put = (HttpPutAttribute)action.Attributes.FirstOrDefault(x => x.GetType() == typeof(HttpPutAttribute)); if (attr_Put != null) { f.Method = HttpMethods.Put.ToLower(); f.Template = string.IsNullOrWhiteSpace(attr_Put.Template) ? string.Empty : attr_Put.Template.ToLower(); lstTemps.Add(f); } HttpDeleteAttribute attr_Delete = (HttpDeleteAttribute)action.Attributes.FirstOrDefault(x => x.GetType() == typeof(HttpDeleteAttribute)); if (attr_Delete != null) { f.Method = HttpMethods.Delete.ToLower(); f.Template = string.IsNullOrWhiteSpace(attr_Delete.Template) ? string.Empty : attr_Delete.Template.ToLower(); lstTemps.Add(f); } RouteAttribute attr_Route = (RouteAttribute)action.Attributes.FirstOrDefault(x => x.GetType() == typeof(RouteAttribute)); if (attr_Route != null) { f.Method = string.IsNullOrWhiteSpace(f.Method) ? HttpMethods.Get.ToLower() : f.Method; f.Template = string.IsNullOrWhiteSpace(attr_Route.Template) ? string.Empty : attr_Route.Template.ToLower(); lstTemps.Add(f); } f.KeyID = 0; f.NgayTao = time; f.Controller = controller.Controller; f.Action = action.Action; f.Path = string.Join('/', "api", f.Controller, f.Template).TrimEnd('/'); } lstFeatures.AddRange(lstTemps); } return(await SaveData(lstFeatures.ToArray())); }