/// <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); }
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); } } } }
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)); }
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); }
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); } } } } }