示例#1
0
        protected void AssertParamParse(string paramKey, string[] paramValues, Type type, object expectedValue, bool hasDefaultValue = false, object defaultValue = null, string overrideParamName = null)
        {
            IModelBinder  binder  = GetModelBinder();
            HttpRequest   request = GetHttpRequest(paramKey, paramValues);
            ActionContext action  = GetActionContext(binder, type, hasDefaultValue, defaultValue, overrideParamName);

            object[] parameters = binder.GetParameterValues(request, action);

            Assert.Equal(1, parameters.Length);
            Assert.Equal(expectedValue, parameters[0]);
        }
示例#2
0
        /// <summary>
        /// Invokes the specified <see cref="ActionContext"/>.
        /// </summary>
        /// <param name="httpCtx">The HTTP context, set by the middleware.</param>
        /// <param name="actionCtx">The action context.</param>
        /// <param name="logger">Logger to use, can be null</param>
        /// <returns></returns>
        public virtual async Task Invoke(HttpContext httpCtx, ActionContext actionCtx, ILogger logger = null)
        {
            logger?.LogInformation("Checking filters");
            ApiFilterRunResult filterResult = await RunFiltersAndCheckIfShouldContinue(httpCtx, actionCtx);

            logger?.LogInformation($"Checking filters completed, can invoke: {filterResult.ShouldContinue}");

            if (!filterResult.ShouldContinue)
            {
                int failedStatusCode = 0;
                if (filterResult.SetResponseCode.HasValue)
                {
                    failedStatusCode = filterResult.SetResponseCode.Value;
                }
                else
                {
                    bool isAuthenticated = httpCtx?.User?.Identity?.IsAuthenticated ?? false;
                    if (isAuthenticated)
                    {
                        failedStatusCode = 403;
                    }
                    else
                    {
                        failedStatusCode = 401;
                    }
                }
                httpCtx.Response.StatusCode = failedStatusCode;
                await httpCtx.Response.WriteAsync(filterResult.SetResponseMessage ?? "request rejected");

                logger?.LogInformation($"returning response with status code: {failedStatusCode}");
                return;
            }

            logger?.LogInformation($"Building controller: {actionCtx.ParentController}");
            LiteController ctrl = _controllerBuilder.Build(actionCtx.ParentController, httpCtx);

            object[] paramValues = _modelBinder.GetParameterValues(httpCtx.Request, actionCtx);
            logger?.LogInformation($"Building controller succeeded: {actionCtx.ParentController}");
            logger?.LogInformation($"Invoking action: {actionCtx}");
            object result = null;
            bool   isVoid = true;

            if (actionCtx.Method.ReturnType == typeof(void))
            {
                actionCtx.Method.Invoke(ctrl, paramValues);
            }
            else if (actionCtx.Method.ReturnType == typeof(Task))
            {
                var   task = (actionCtx.Method.Invoke(ctrl, paramValues) as Task);
                await task;
            }
            else if (actionCtx.Method.ReturnType.IsConstructedGenericType && actionCtx.Method.ReturnType.GetGenericTypeDefinition() == typeof(Task <>))
            {
                isVoid = false;
                var task = (dynamic)(actionCtx.Method.Invoke(ctrl, paramValues));
                result = await task;
            }
            else
            {
                isVoid = false;
                result = actionCtx.Method.Invoke(ctrl, paramValues);
            }

            int?overridenResponseCode = httpCtx.GetResponseStatusCode();

            if (overridenResponseCode.HasValue)
            {
                httpCtx.Response.StatusCode = overridenResponseCode.Value;
            }
            else
            {
                int statusCode = 405; // method not allowed
                switch (httpCtx.Request.Method.ToUpper())
                {
                case "GET": statusCode = 200; break;

                case "POST": statusCode = 201; break;

                case "PUT": statusCode = 201; break;

                case "DELETE": statusCode = 204; break;
                }
                httpCtx.Response.StatusCode = statusCode;
            }

            httpCtx.Response.Headers.Add("X-Powered-By-Middleware", "LiteApi");
            var additionalHeaders = httpCtx.GetResponseHeaders(true);

            if (additionalHeaders != null)
            {
                foreach (var header in additionalHeaders)
                {
                    httpCtx.Response.Headers.Add(header.Key, header.Value);
                }
            }

            if (isVoid)
            {
                logger?.LogInformation("Not serializing result from invoked action, action is void or void task");
            }
            else
            {
                logger?.LogInformation("Serializing result from invoked action");
                if (actionCtx.IsReturningLiteActionResult)
                {
                    await(result as ILiteActionResult).WriteResponse(httpCtx, actionCtx);
                }
                else
                {
                    httpCtx.Response.ContentType = "application/json";
                    await httpCtx.Response.WriteAsync(_jsonSerializer.Serialize(result));
                }
            }
        }