예제 #1
0
        /// <summary>
        /// Callback invoked to set per-controller overrides for this controllerDescriptor.
        /// </summary>
        /// <param name="controllerSettings">The controller settings to initialize.</param>
        /// <param name="controllerDescriptor">The controller descriptor. Note that the <see
        /// cref="T:System.Web.Http.Controllers.HttpControllerDescriptor" /> can be associated with the derived
        /// controller type given that <see cref="T:System.Web.Http.Controllers.IControllerConfiguration" /> is
        /// inherited.</param>
        public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor)
        {
            if (controllerSettings == null)
            {
                throw new ArgumentNullException("controllerSettings");
            }

            if (controllerDescriptor == null)
            {
                throw new ArgumentNullException("controllerDescriptor");
            }

            ServicesContainer services = controllerSettings.Services;

            Contract.Assert(services != null);

            IContainerMetadata containerMetadata = controllerDescriptor.GetContainerMetadata();

            // Replace the action selector with one that is based on the OData routing conventions
            IHttpActionSelector originalActionSelector = services.GetActionSelector();
            IHttpActionSelector actionSelector;

            if (containerMetadata != null)
            {
                // ContainerMetadata was stored with the HttpControllerDescriptor - so use our "special" ActionSelector
                actionSelector = new EntityRepositoryActionSelector(containerMetadata, originalActionSelector);
            }
            else
            {
                // No ContainerMetadata stored with the HttpControllerDescriptor - so use the standard odata ActionSelector
                actionSelector = new ODataActionSelector(originalActionSelector);
            }
            controllerSettings.Services.Replace(typeof(IHttpActionSelector), actionSelector);
        }
예제 #2
0
        private void ExploreRouteActions(IHttpRoute route, string localPath, HttpControllerDescriptor controllerDescriptor, Collection <ApiDescription> apiDescriptions)
        {
            ServicesContainer controllerServices = controllerDescriptor.Configuration.Services;
            ILookup <string, HttpActionDescriptor> actionMappings = controllerServices.GetActionSelector().GetActionMapping(controllerDescriptor);
            string actionVariableValue;

            if (actionMappings != null)
            {
                if (_actionVariableRegex.IsMatch(localPath))
                {
                    // unbound action variable, {action}
                    foreach (IGrouping <string, HttpActionDescriptor> actionMapping in actionMappings)
                    {
                        // expand {action} variable
                        actionVariableValue = actionMapping.Key;
                        string expandedLocalPath = _actionVariableRegex.Replace(localPath, actionVariableValue);
                        PopulateActionDescriptions(actionMapping, actionVariableValue, route, expandedLocalPath, apiDescriptions);
                    }
                }
                else if (route.Defaults.TryGetValue(ActionVariableName, out actionVariableValue))
                {
                    // bound action variable, { action = "actionName" }
                    PopulateActionDescriptions(actionMappings[actionVariableValue], actionVariableValue, route, localPath, apiDescriptions);
                }
                else
                {
                    // no {action} specified, e.g. {controller}/{id}
                    foreach (IGrouping <string, HttpActionDescriptor> actionMapping in actionMappings)
                    {
                        PopulateActionDescriptions(actionMapping, null, route, localPath, apiDescriptions);
                    }
                }
            }
        }
예제 #3
0
        public virtual Task <HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
        {
            if (_initialized)
            {
                // if user has registered a controller factory which produces the same controller instance, we should throw here
                throw Error.InvalidOperation(SRResources.CannotSupportSingletonInstance, typeof(ApiController).Name, typeof(IHttpControllerActivator).Name);
            }

            Initialize(controllerContext);

            // We can't be reused, and we know we're disposable, so make sure we go away when
            // the request has been completed.
            if (Request != null)
            {
                Request.RegisterForDispose(this);
            }

            HttpControllerDescriptor controllerDescriptor = controllerContext.ControllerDescriptor;
            ServicesContainer        controllerServices   = controllerDescriptor.Configuration.Services;

            HttpActionDescriptor actionDescriptor = controllerServices.GetActionSelector().SelectAction(controllerContext);

            ActionContext.ActionDescriptor = actionDescriptor;
            if (Request != null)
            {
                Request.SetActionDescriptor(actionDescriptor);
            }

            FilterGrouping filterGrouping = actionDescriptor.GetFilterGrouping();

            IActionFilter[]         actionFilters         = filterGrouping.ActionFilters;
            IAuthenticationFilter[] authenticationFilters = filterGrouping.AuthenticationFilters;
            IAuthorizationFilter[]  authorizationFilters  = filterGrouping.AuthorizationFilters;
            IExceptionFilter[]      exceptionFilters      = filterGrouping.ExceptionFilters;

            IHttpActionResult result = new ActionFilterResult(actionDescriptor.ActionBinding, ActionContext,
                                                              controllerServices, actionFilters);

            if (authorizationFilters.Length > 0)
            {
                result = new AuthorizationFilterResult(ActionContext, authorizationFilters, result);
            }
            if (authenticationFilters.Length > 0)
            {
                result = new AuthenticationFilterResult(ActionContext, this, authenticationFilters, result);
            }
            if (exceptionFilters.Length > 0)
            {
                IExceptionLogger  exceptionLogger  = ExceptionServices.GetLogger(controllerServices);
                IExceptionHandler exceptionHandler = ExceptionServices.GetHandler(controllerServices);
                result = new ExceptionFilterResult(ActionContext, exceptionFilters, exceptionLogger, exceptionHandler,
                                                   result);
            }

            return(result.ExecuteAsync(cancellationToken));
        }
예제 #4
0
        public virtual Task <HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
        {
            if (_request != null)
            {
                // if user has registered a controller factory which produces the same controller instance, we should throw here
                throw Error.InvalidOperation(SRResources.CannotSupportSingletonInstance, typeof(ApiController).Name, typeof(IHttpControllerActivator).Name);
            }

            Initialize(controllerContext);

            // We can't be reused, and we know we're disposable, so make sure we go away when
            // the request has been completed.
            if (_request != null)
            {
                _request.RegisterForDispose(this);
            }

            HttpControllerDescriptor controllerDescriptor = controllerContext.ControllerDescriptor;
            ServicesContainer        controllerServices   = controllerDescriptor.Configuration.Services;
            HttpActionDescriptor     actionDescriptor     = controllerServices.GetActionSelector().SelectAction(controllerContext);
            HttpActionContext        actionContext        = new HttpActionContext(controllerContext, actionDescriptor);

            IEnumerable <FilterInfo> filters = actionDescriptor.GetFilterPipeline();

            FilterGrouping filterGrouping = new FilterGrouping(filters);

            IEnumerable <IActionFilter>        actionFilters        = filterGrouping.ActionFilters;
            IEnumerable <IAuthorizationFilter> authorizationFilters = filterGrouping.AuthorizationFilters;
            IEnumerable <IExceptionFilter>     exceptionFilters     = filterGrouping.ExceptionFilters;

            // Func<Task<HttpResponseMessage>>
            Task <HttpResponseMessage> result = InvokeActionWithAuthorizationFilters(actionContext, cancellationToken, authorizationFilters, () =>
            {
                HttpActionBinding actionBinding = actionDescriptor.ActionBinding;
                Task bindTask = actionBinding.ExecuteBindingAsync(actionContext, cancellationToken);
                return(bindTask.Then <HttpResponseMessage>(() =>
                {
                    _modelState = actionContext.ModelState;
                    Func <Task <HttpResponseMessage> > invokeFunc = InvokeActionWithActionFilters(actionContext, cancellationToken, actionFilters, () =>
                    {
                        return controllerServices.GetActionInvoker().InvokeActionAsync(actionContext, cancellationToken);
                    });
                    return invokeFunc();
                }));
            })();

            result = InvokeActionWithExceptionFilters(result, actionContext, cancellationToken, exceptionFilters);

            return(result);
        }
        /// <summary>
        /// Callback invoked to set per-controller overrides for this controllerDescriptor.
        /// </summary>
        /// <param name="controllerSettings">The controller settings to initialize.</param>
        /// <param name="controllerDescriptor">The controller descriptor. Note that the <see
        /// cref="T:System.Web.Http.Controllers.HttpControllerDescriptor" /> can be associated with the derived
        /// controller type given that <see cref="T:System.Web.Http.Controllers.IControllerConfiguration" /> is
        /// inherited.</param>
        public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor)
        {
            if (controllerSettings == null)
            {
                throw Error.ArgumentNull("controllerSettings");
            }

            if (controllerDescriptor == null)
            {
                throw Error.ArgumentNull("controllerDescriptor");
            }

            ServicesContainer services = controllerSettings.Services;

            Contract.Assert(services != null);

            // Replace the action selector with one that is based on the OData routing conventions
            IHttpActionSelector originalActionSelector = services.GetActionSelector();
            IHttpActionSelector actionSelector         = new ODataActionSelector(originalActionSelector);

            controllerSettings.Services.Replace(typeof(IHttpActionSelector), actionSelector);
        }
예제 #6
0
 private void ExploreRouteActions(IHttpRoute route, string localPath, HttpControllerDescriptor controllerDescriptor, Collection <ApiDescription> apiDescriptions)
 {
     // exclude controllers that are marked with route attributes.
     if (!controllerDescriptor.GetCustomAttributes <IHttpRouteInfoProvider>(inherit: false).Any())
     {
         ServicesContainer controllerServices = controllerDescriptor.Configuration.Services;
         ILookup <string, HttpActionDescriptor> actionMappings = controllerServices.GetActionSelector().GetActionMapping(controllerDescriptor);
         string actionVariableValue;
         if (actionMappings != null)
         {
             if (_actionVariableRegex.IsMatch(localPath))
             {
                 // unbound action variable, {action}
                 foreach (IGrouping <string, HttpActionDescriptor> actionMapping in actionMappings)
                 {
                     // expand {action} variable
                     actionVariableValue = actionMapping.Key;
                     string expandedLocalPath = _actionVariableRegex.Replace(localPath, actionVariableValue);
                     PopulateActionDescriptions(actionMapping, actionVariableValue, route, expandedLocalPath, apiDescriptions, controllerDescriptor);
                 }
             }
             else if (route.Defaults.TryGetValue(RouteKeys.ActionKey, out actionVariableValue))
             {
                 // bound action variable, { action = "actionName" }
                 PopulateActionDescriptions(actionMappings[actionVariableValue], actionVariableValue, route, localPath, apiDescriptions, controllerDescriptor);
             }
             else
             {
                 // no {action} specified, e.g. {controller}/{id}
                 foreach (IGrouping <string, HttpActionDescriptor> actionMapping in actionMappings)
                 {
                     PopulateActionDescriptions(actionMapping, null, route, localPath, apiDescriptions, controllerDescriptor);
                 }
             }
         }
     }
 }