Example #1
0
        public IActionResult Invoke(RouteMatch match, TcpClient client, RequestContext context)
        {
            if (match is null)
            {
                throw new ArgumentNullException($"{nameof(match)} cannot be null.", nameof(match));
            }

            if (match.ActionMatch.Action is null)
            {
                throw new ArgumentNullException($"match.HttpMethod.Template");
            }

            if (match.ActionMatch.Action.ReturnType != typeof(IActionResult))
            {
                throw new NotSupportedException($"Invalid Match: Invalid Action ReturnType:{match.ActionMatch.Action.ReturnType}. " +
                                                $"ReturnType must be {typeof(IActionResult)}");
            }

            if (match.ActionMatch.HttpMethod == null)
            {
                throw new ArgumentNullException($"{nameof(match)}.{nameof(match.ActionMatch.HttpMethod)} cannot be null.");
            }

            if (match.ActionMatch.HttpMethod.Template == null)
            {
                throw new ArgumentNullException($"{nameof(match)}.{nameof(match.ActionMatch.HttpMethod)}.{nameof(match.ActionMatch.HttpMethod.Template)} cannot be null.");
            }

            if (client is null)
            {
                throw new ArgumentNullException($"{nameof(client)} cannot be null.", nameof(client));
            }

            Assert.NotNull(context, nameof(context));
            Assert.NotNull(context.Content, $"{nameof(context)}.{nameof(context.Content)}.");

            Assert.NotNull(match.MatchingActionPathSegments, $"{nameof(match)}.{nameof(match.MatchingActionPathSegments)}");
            Assert.NotNull(match.TemplatePathSegments, $"{nameof(match)}.{nameof(match.TemplatePathSegments)}");

            Assert.That(match.MatchingActionPathSegments.Length == match.TemplatePathSegments.Length,
                        "Invalid match: actionPathLength must be equal to templatePathLength");

            RequestBodyExtractor bodyExtractor = new RequestBodyExtractor(context);

            object        controller      = BuildController(match, client, context);
            List <object> invokeArguments = new List <object>();

            foreach (ParameterInfo actionParameter in match.ActionMatch.Action.GetParameters())
            {
                string correspondingParameter = string.Empty;

                int actionParameterIndex = Array.IndexOf(match.TemplatePathSegments, $"{{{actionParameter.Name}}}");

                if (actionParameterIndex == -1)
                {
                    if (context.Parameters.HeaderEntries.ContainsKey(actionParameter.Name))
                    {
                        correspondingParameter = ExtractFromRequestHeader(context, actionParameter);
                    }
                    else
                    {
                        byte[] bodyContent = ExtractFromRequestBody(match, context, bodyExtractor, actionParameter);
                        correspondingParameter = Encoding.UTF8.GetString(bodyContent);
                    }
                }
                else
                {
                    string routeParameter = match.MatchingActionPathSegments[actionParameterIndex];
                    correspondingParameter = ConvertToDeserializeableString(routeParameter, actionParameter);
                }

                try
                {
                    if (actionParameter.ParameterType == typeof(Guid))
                    {
                        if (Guid.TryParse(correspondingParameter, out Guid result))
                        {
                            invokeArguments.Add(result);
                        }
                        else
                        {
                            throw new EndPointHandlerException(
                                      $"Error parsing expected Guid- Parameter: {actionParameter.Name}. "
                                      + $"Value: {correspondingParameter} could not be parsed."
                                      );
                        }
                    }
                    else
                    {
                        object result = JsonSerializer.Deserialize(correspondingParameter, actionParameter.ParameterType);
                        invokeArguments.Add(result);
                    }
                }
                catch (JsonException jsonEx)
                {
                    throw BuildEndpointHandlerException(
                              $"Could not Resolve Action Parameter:{actionParameter.Name} of Type: {actionParameter.ParameterType}.{Environment.NewLine}",
                              match,
                              jsonEx
                              );
                }
            }

            return((IActionResult)match.ActionMatch.Action.Invoke(controller, invokeArguments.ToArray()));
        }
Example #2
0
        private static byte[] ExtractFromRequestBody(RouteMatch match, RequestContext context, RequestBodyExtractor bodyExtractor, ParameterInfo actionParameter)
        {
            if (supportedContentTypes.Any(sct => sct.Equals(context.Content.ContentType, StringComparison.OrdinalIgnoreCase)))
            {
                if (bodyExtractor.BodyExtracted)
                {
                    return(bodyExtractor.Cache.ToArray());
                }
                else
                {
                    try
                    {
                        return(bodyExtractor.Extract());
                    }
                    catch (RequestBodyExtractorException bodyExtractorEx)
                    {
                        EndPointHandlerException error = BuildEndpointHandlerException(
                            $"Could not Resolve Action Parameter:{actionParameter.Name} of Type: {actionParameter.ParameterType}.",
                            match,
                            bodyExtractorEx
                            );

                        throw error;
                    }
                }
            }
            else
            {
                NotSupportedException innerException = new NotSupportedException(
                    $"Could not Resolve Action Parameter:{actionParameter.Name} of Type: {actionParameter.ParameterType}. " +
                    $"Invalid Content-Type:{context.Content.ContentType}. " +
                    $"Supported Contenttypes are: {string.Join(',', supportedContentTypes)}");

                throw BuildEndpointHandlerException(match, innerException);
            }
        }