示例#1
0
            public static string GetMethodDetails(HttpController controller, HttpEndpoint endpoint, bool async, bool raw)
            {
                var cancellationToken = endpoint.GetRequestModifiers().OfType <CancellationTokenModifier>().SingleOrDefault();
                var clientDependency  = new ClientDependency($"I{Settings.ClientInterfaceName}Wrapper");

                var requestModifiers = endpoint.GetRequestModifiers().ToList();

                var    bodyParameter = endpoint.GetBodyParameter();
                string bodyVariable  = bodyParameter?.Name ?? "null";

                var responseTypes = endpoint.GetResponseTypes();

                var routeConstraints = endpoint.GetRouteConstraints(controller);

                return
                    ($@"{string.Join(Environment.NewLine, routeConstraints.Select(WriteRouteConstraint).NotNull())}
{GetEndpointInfoVariables(controller, endpoint)}
string url = $@""{GetRoute(controller, endpoint, async)}"";
HttpResponseMessage response = null;
response = {GetAwait(async)}HttpOverride.GetResponseAsync({GetHttpMethod(endpoint.HttpType)}, url, null, {cancellationToken.Name}){GetAsyncEnding(async)};

if(response == null)
{{
	try
	{{
		response = {GetAwait(async)}{clientDependency.GetDependencyName($"I{Settings.ClientInterfaceName}")}.{nameof(IClientWrapper.ClientWrapper)}
					.Request(url)
{string.Join($"				{Environment.NewLine}", requestModifiers.Select(WriteRequestModifiers).NotNull())}
					.AllowAnyHttpStatus()
					{GetHttpMethod(endpoint)}
					{GetAsyncEnding(async)};
	}}
	catch({nameof(FlurlHttpException)} fhex)
	{{
{WriteResponseType(responseTypes.OfType<ExceptionResponseType>().Single(), async, false)}
{WriteErrorActionResultReturn(endpoint, async, raw)}
	}}

	{GetAwait(async)}HttpOverride.OnNonOverridedResponseAsync({GetHttpMethod(endpoint.HttpType)}, url, {bodyVariable}, response, {cancellationToken.Name}){GetAsyncEnding(async)};
}}
{string.Join(Environment.NewLine, responseTypes.Where(x => x.GetType() != typeof(ExceptionResponseType)).Select(x => WriteResponseType(x, async, raw)).NotNull())}
{WriteActionResultReturn(endpoint, async, raw)}");
            }
示例#2
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);
        }