示例#1
0
            public static string GetEndpointInfoVariables(HttpController controller, HttpEndpoint endpoint)
            {
                var controllerVar = $@"var {Constants.ControllerRouteReserved} = ""{endpoint.Parent.Name}"";";
                var actionVar     = $@"var {Constants.ActionRouteReserved} = ""{endpoint.Name}"";";


                if (!endpoint.GetFullRoute(controller).Contains($"[{Constants.ControllerRouteReserved}]"))
                {
                    controllerVar = null;
                }

                if (!endpoint.GetFullRoute(controller).Contains($"[{Constants.ActionRouteReserved}]"))
                {
                    actionVar = null;
                }


                return
                    ($@"{controllerVar}
{actionVar}");
            }
示例#2
0
            public static string GetRoute(HttpController controller, HttpEndpoint endpoint, bool async)
            {
                const string RouteParseRegex = @"{([^}]+)}";

                string routeUnformatted = endpoint.GetFullRoute(controller);

                var patterns = Regex.Matches(routeUnformatted, RouteParseRegex);

                var routeParameters = endpoint.GetRouteParameters().ToList();
                var queryParameters = endpoint.GetQueryParameters().ToList();

                foreach (var group in patterns)
                {
                    Match    match    = group as Match;
                    string   filtered = match.Value.Replace("{", "").Replace("}", "");
                    string[] split    = filtered.Split(new char[] { ':' });

                    string variable = split[0];


                    if (!routeParameters.Any(x => x.Name.Equals(variable, StringComparison.CurrentCultureIgnoreCase)))
                    {
                        throw new Exception($"{variable} is missing from passed in parameters. Please check your route.");
                    }
                    var parameter = routeParameters.SingleOrDefault(x => x.Name.Equals(variable, StringComparison.CurrentCultureIgnoreCase));
                    if (Helpers.IsRoutableType(parameter.Type))
                    {
                        routeUnformatted = routeUnformatted.Replace(match.Value, $"{{{Helpers.GetRouteStringTransform(parameter.Name, parameter.Type)}}}");
                    }
                }

                if (queryParameters.Any())
                {
                    string queryString = $"?{string.Join("&", queryParameters.Select(x => WriteQueryParameter(x, async)))}";

                    routeUnformatted += $"{queryString}";
                }



                routeUnformatted = routeUnformatted.Replace($"[{Constants.ControllerRouteReserved}]", $"{{{Constants.ControllerRouteReserved}}}");
                routeUnformatted = routeUnformatted.Replace($"[{Constants.ActionRouteReserved}]", $"{{{Constants.ActionRouteReserved}}}");
                return(routeUnformatted);
            }
示例#3
0
        private static HttpEndpoint ReadMethodAsHttpEndpoint(HttpController parent, MethodDeclarationSyntax syntax)
        {
            var attributes = syntax.DescendantNodes().OfType <AttributeListSyntax>().SelectMany(x => x.Attributes).ToList();

            var endpoint = new HttpEndpoint(parent);

            endpoint.Name = syntax.Identifier.ValueText.CleanMethodName();


            endpoint.Virtual  = syntax.Modifiers.Any(x => x.Text == "virtual");
            endpoint.Override = syntax.Modifiers.Any(x => x.Text == "override");
            endpoint.New      = syntax.Modifiers.Any(x => x.Text == "new");


            //Ignore generator attribute
            endpoint.Ignored = attributes.SingleOrDefault(x => x.Name.ToFullString().MatchesAttribute(nameof(NotGeneratedAttribute))) != null;


            //Route Attribute

            var routeAttribute = attributes.SingleOrDefault(x => x.Name.ToFullString().MatchesAttribute(nameof(RouteAttribute)));

            if (routeAttribute != null)            //Fetch route from RouteAttribute
            {
                endpoint.Route = new HttpRoute(routeAttribute.ArgumentList.Arguments.ToFullString().Replace("\"", "").Trim());
            }


            //HTTP Attribute
            var knownHttpAttributes = new List <string>
            {
                $"{Constants.Http}{HttpAttributeType.Delete}",
                $"{Constants.Http}{HttpAttributeType.Get}",
                $"{Constants.Http}{HttpAttributeType.Patch}",
                $"{Constants.Http}{HttpAttributeType.Post}",
                $"{Constants.Http}{HttpAttributeType.Put}",
            };

            var httpAttribute = attributes.SingleOrDefault(x => knownHttpAttributes.Any(y => x.Name.ToFullString().MatchesAttribute(y)));

            if (httpAttribute == null)
            {
                endpoint.Ignored = true;
            }
            else
            {
                var httpType = (HttpAttributeType)Enum.Parse(typeof(HttpAttributeType),
                                                             httpAttribute.Name
                                                             .ToFullString()
                                                             .Replace(Constants.Http, "")
                                                             .Replace(Constants.Attribute, ""));

                endpoint.HttpType = Helpers.HttpMethodFromEnum(httpType);
            }



            if (endpoint.Route == null && httpAttribute?.ArgumentList != null)            //If Route was never fetched from RouteAttribute or if they used the Http(template) override
            {
                endpoint.Route = new HttpRoute(httpAttribute.ArgumentList.Arguments.ToFullString().Replace("\"", "").Trim());
            }

            //Ignore method if it doesn't have a route or http attribute
            if (endpoint.Route == null && httpAttribute == null)
            {
                endpoint.Ignored = true;
                return(endpoint);
            }


            //Obsolete Attribute
            var obsoleteAttribute = attributes.SingleOrDefault(x => x.Name.ToFullString().MatchesAttribute(nameof(ObsoleteAttribute)));

            if (obsoleteAttribute != null)
            {
                endpoint.Obsolete        = true;
                endpoint.ObsoleteMessage = obsoleteAttribute.ArgumentList.Arguments.ToFullString().Replace("\"", "").Trim();
            }

            //Authorize Attribute
            endpoint.IsSecured = attributes.SingleOrDefault(x => x.Name.ToFullString().MatchesAttribute(nameof(AuthorizeAttribute))) != null;


            //Response types
            var responseTypes = attributes.Where(x => x.Name.ToFullString().MatchesAttribute(nameof(ProducesResponseTypeAttribute)));
            var responses     = responseTypes.Select(x => new ResponseTypeDefinition(x)).ToList();

            responses.Add(new ResponseTypeDefinition(true));

            endpoint.ResponseTypes = responses.Select(x => new ResponseType(x.Type, Helpers.EnumParse <HttpStatusCode>(x.StatusValue))).ToList();

            var duplicateResponseTypes = endpoint.GetResponseTypes().GroupBy(x => x.Status).Where(x => x.Count() > 1).ToList();

            if (duplicateResponseTypes.Any())
            {
                throw new NotSupportedException($"Endpoint has multiple response types of the same status defined. {string.Join(", ", duplicateResponseTypes.Select(x => x.Key?.ToString()))}");
            }
            //Add after so we don't get duplicate error from the null Status
            endpoint.ResponseTypes.Add(new ExceptionResponseType());



            var parameters = syntax.ParameterList.Parameters.Select(x => new ParameterDefinition(x, endpoint.GetFullRoute(parent))).ToList();


            var routeParams = parameters.Where(x => x.Options.FromRoute).Select(x => new RouteParameter(x.RouteName, x.Type, x.Default)).ToList();
            var queryParams = parameters.Where(x => x.Options.FromQuery).Select(x => new QueryParameter(x.Options.QueryName, x.Type, x.Default, x.Options.QueryObject)).ToList();
            var bodyParams  = parameters.Where(x => x.Options.FromBody).Select(x => new BodyParameter(x.Name, x.Type, x.Default)).SingleOrDefault();


            endpoint.Parameters = routeParams.Cast <IParameter>().Union(queryParams).Union(new List <IParameter> {
                bodyParams
            }).NotNull().ToList();

            endpoint.Parameters.Add(new CancellationTokenModifier());
            endpoint.Parameters.Add(new CookieModifier());
            endpoint.Parameters.Add(new HeadersModifier());
            endpoint.Parameters.Add(new TimeoutModifier());
            if (endpoint.IsSecured)
            {
                endpoint.Parameters.Add(new SecurityModifier());
            }


            var parameterHeaders = attributes.Where(x => x.Name.ToFullString().MatchesAttribute(nameof(HeaderParameterAttribute)))
                                   .Select(x => new ParameterHeaderDefinition(x))
                                   .ToList();

            endpoint.ParameterHeader = parameterHeaders.Select(x => new ParameterHeader(x.Name, x.Type, x.DefaultValue)).ToList();



            var headers = attributes.Where(x => x.Name.ToFullString().MatchesAttribute(nameof(IncludeHeaderAttribute)))
                          .Select(x => new HeaderDefinition(x))
                          .ToList();

            endpoint.ConstantHeader = headers.Select(x => new ConstantHeader(x.Name, x.Value)).ToList();


            var rawReturnType = syntax.ReturnType?.ToFullString();

            HashSet <string> returnContainerTypes = new HashSet <string>()
            {
                typeof(ValueTask).FullName,
                typeof(Task).FullName,
                typeof(ActionResult).FullName
            };


            var returnType = Helpers.GetTypeFromString(rawReturnType.Trim());

            while (returnContainerTypes.Any(x => Helpers.IsType(x, returnType?.Name)))
            {
                returnType = returnType.Arguments.SingleOrDefault();
            }

            if (Helpers.IsType(typeof(IActionResult).FullName, returnType?.Name))
            {
                returnType = null;
            }

            if (returnType?.Name == "void" ||
                (Helpers.IsType(typeof(Task).FullName, returnType?.Name) && (!returnType?.Arguments.Any() ?? false)))
            {
                returnType = null;
            }

            HashSet <string> fileResults = new HashSet <string>()
            {
                nameof(PhysicalFileResult),
                nameof(FileResult),
                nameof(FileContentResult),
                nameof(FileStreamResult),
                nameof(VirtualFileResult)
            };

            if (fileResults.Any(x => Helpers.IsType(x, returnType?.Name)))
            {
                returnType             = new Helpers.TypeString(typeof(Stream).FullName);
                endpoint.ReturnsStream = true;
            }

            rawReturnType = returnType?.ToString();

            endpoint.ReturnType = rawReturnType;



            var duplicateParameters = endpoint.GetParametersWithoutResponseTypes().GroupBy(x => x.Name).Where(x => x.Count() > 1).ToList();

            if (duplicateParameters.Any())
            {
                throw new NotSupportedException($"Endpoint has multiple parameters of the same name defined. {string.Join(", ", duplicateParameters.Select(x => x.Key?.ToString()))}");
            }



            return(endpoint);
        }