private ControllerActionDescriptor CreateActionDescriptor( string httpMethod, string routeTemplate, string actionFixtureName) { var descriptor = new ControllerActionDescriptor(); descriptor.SetProperty(new ApiDescriptionActionData()); descriptor.DisplayName = actionFixtureName; descriptor.ActionConstraints = new List<IActionConstraintMetadata> { new HttpMethodConstraint(new[] { httpMethod }) }; descriptor.AttributeRouteInfo = new AttributeRouteInfo { Template = routeTemplate }; descriptor.MethodInfo = typeof(ActionFixtures).GetMethod(actionFixtureName); if (descriptor.MethodInfo == null) throw new InvalidOperationException( string.Format("{0} is not declared in ActionFixtures", actionFixtureName)); descriptor.Parameters = descriptor.MethodInfo.GetParameters() .Select(paramInfo => new ParameterDescriptor { Name = paramInfo.Name, ParameterType = paramInfo.ParameterType, BindingInfo = BindingInfo.GetBindingInfo(paramInfo.GetCustomAttributes(false)) }) .ToList(); // Set some additional properties - typically done via IApplicationModelConvention var attributes = descriptor.MethodInfo.GetCustomAttributes(true); descriptor.Properties.Add("ActionAttributes", attributes); descriptor.Properties.Add("IsObsolete", attributes.OfType<ObsoleteAttribute>().Any()); return descriptor; }
public ControllerActionInvoker( [NotNull] ActionContext actionContext, [NotNull] IReadOnlyList<IFilterProvider> filterProviders, [NotNull] IControllerFactory controllerFactory, [NotNull] ControllerActionDescriptor descriptor, [NotNull] IInputFormattersProvider inputFormatterProvider, [NotNull] IControllerActionArgumentBinder controllerActionArgumentBinder, [NotNull] IModelBinderProvider modelBinderProvider, [NotNull] IModelValidatorProviderProvider modelValidatorProviderProvider, [NotNull] IValueProviderFactoryProvider valueProviderFactoryProvider, [NotNull] IScopedInstance<ActionBindingContext> actionBindingContextAccessor, [NotNull] ITempDataDictionary tempData) : base( actionContext, filterProviders, inputFormatterProvider, modelBinderProvider, modelValidatorProviderProvider, valueProviderFactoryProvider, actionBindingContextAccessor) { _descriptor = descriptor; _controllerFactory = controllerFactory; _argumentBinder = controllerActionArgumentBinder; _tempData = tempData; if (descriptor.MethodInfo == null) { throw new ArgumentException( Resources.FormatPropertyOfTypeCannotBeNull("MethodInfo", typeof(ControllerActionDescriptor)), "descriptor"); } }
public void CreateController_UsesControllerActivatorToInstantiateController() { // Arrange var expected = new MyController(); var actionDescriptor = new ControllerActionDescriptor { ControllerTypeInfo = typeof(MyController).GetTypeInfo() }; var httpContext = new DefaultHttpContext(); httpContext.RequestServices = GetServices(); var actionContext = new ActionContext(httpContext, new RouteData(), actionDescriptor); var activator = new Mock<IControllerActivator>(); activator.Setup(a => a.Create(actionContext, typeof(MyController))) .Returns(expected) .Verifiable(); var controllerFactory = new DefaultControllerFactory(activator.Object); // Act var result = controllerFactory.CreateController(actionContext); // Assert var controller = Assert.IsType<MyController>(result); Assert.Same(expected, controller); activator.Verify(); }
public void VisiblityCanBeChangedViaAttribute(Type controllerType, bool exposeAllRoutes, bool expected) { var controllerName = controllerType.Name.Replace("Controller", string.Empty); var config = new RouteJsConfiguration { ExposeAllRoutes = exposeAllRoutes }; var descriptor = new ControllerActionDescriptor { ControllerName = controllerName, ControllerTypeInfo = controllerType.GetTypeInfo(), }; var descriptorProvider = new Mock<IActionDescriptorsCollectionProvider>(); descriptorProvider.Setup(x => x.ActionDescriptors).Returns(new ActionDescriptorsCollection( new List<ActionDescriptor> { descriptor }, version: 1 )); var filter = new DefaultRouteFilter(config, descriptorProvider.Object); var result = filter.AllowRoute(new RouteInfo { Defaults = new Dictionary<string, object> { {"controller", controllerName}, }, }); Assert.Equal(expected, result); }
public void GetApiDescription_IgnoresActionWithoutApiExplorerData() { // Arrange var action = new ControllerActionDescriptor(); // Act var descriptions = GetApiDescriptions(action); // Assert Assert.Empty(descriptions); }
/// <summary> /// Get the name of exception policy to handle the exception. /// </summary> /// <param name="context">The current <see cref="ExceptionContext"/>.</param> /// <returns>The name of exception policy to handle the exception.</returns> protected virtual string GetExceptionPolicy(Filters.ExceptionContext context) { Guard.ArgumentNotNull(context, nameof(context)); if (!string.IsNullOrEmpty(this.ExceptionPolicy)) { return(this.ExceptionPolicy); } ControllerActionDescriptor actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; if (null != actionDescriptor) { var attribute = actionDescriptor.MethodInfo.GetCustomAttribute <ExceptionPolicyAttribute>() ?? actionDescriptor.ControllerTypeInfo.GetCustomAttribute <ExceptionPolicyAttribute>(); if (null != attribute) { return(attribute.PolicyName); } } return(_options.ExceptionPolicy); }
public void Authen_Withusermodifyprivilege_Test() { ControllerActionDescriptor controllerActionDescriptor = new ControllerActionDescriptor(); controllerActionDescriptor.MethodInfo = this.GetType().GetMethod(nameof(ModifyUser), BindingFlags.Public | BindingFlags.Instance); var actionContext = new ActionContext(); actionContext.ActionDescriptor = controllerActionDescriptor; actionContext.HttpContext = new Mock <HttpContext>().Object; actionContext.RouteData = new RouteData(); var filterContext = new ExceptionContext(actionContext, new List <IFilterMetadata>()); var authenQuery = new ExecuteContextAuthen(filterContext, new UserWithUserQueryPrivilege()); Assert.IsTrue(authenQuery.Authen(new DefaultParceAuthenTypeAccordParameterName()) == EnumAuthenResult.NotAuthened, "有用户查询权限的人访问 ModifyUser 时不允许访问"); var authenModify = new ExecuteContextAuthen(filterContext, new UserWithUserModifyPrivilege()); Assert.IsTrue(authenModify.Authen(new DefaultParceAuthenTypeAccordParameterName()) == EnumAuthenResult.Authened, "有用户查询权限的人访问 ModifyUser 时不允许访问"); }
public void FindsActionWithExactContentRouteType() { var actionA = new ControllerActionDescriptor { ControllerName = "lorem", MethodInfo = typeof(MyController).GetMethod(nameof(MyController.ActionWithTypeAParameter)) }; var actionB = new ControllerActionDescriptor { ControllerName = "lorem", MethodInfo = typeof(MyController).GetMethod(nameof(MyController.ActionWithTypeBParameter)) }; var serviceProvider = Mock.Of <IServiceProvider>(); var actions = Mock.Of <IActionDescriptorCollectionProvider>(); Mock.Get(serviceProvider).Setup(s => s.GetService(typeof(IActionDescriptorCollectionProvider))).Returns(actions); Mock.Get(actions).SetupGet(a => a.ActionDescriptors).Returns(new ActionDescriptorCollection(new List <ActionDescriptor> { actionA, actionB }.AsReadOnly(), 0)); var result = new ContentRouteActionFinder(serviceProvider).Find("lorem", new MyContentA()); Assert.Same(actionA, result); }
/// <summary> /// Infers the name of the page number parameter. /// </summary> /// <param name="cad">The <see cref="ControllerActionDescriptor"/> which contains the controller action definition information.</param> /// <returns>The name of the page number parameter, or null, if the name cannot be inferred.</returns> private static string InferPageNumberParameterName(ControllerActionDescriptor cad) { if (cad.Parameters.Any(p => p.ParameterType == typeof(int) && p.Name.Equals("page", StringComparison.OrdinalIgnoreCase))) { return("page"); } if (cad.Parameters.Any(p => p.ParameterType == typeof(int) && p.Name.Equals("pageNumber", StringComparison.OrdinalIgnoreCase))) { return("pageNumber"); } var pageNumberParameter = cad.MethodInfo.GetParameters().FirstOrDefault(x => x.IsDefined(typeof(PageNumberAttribute))); if (pageNumberParameter != null) { return(pageNumberParameter.Name); } return(null); }
private static string GetActionDesciption(ControllerActionDescriptor actionDescriptor) { // controller and action details StringBuilder action = new StringBuilder(); if (actionDescriptor.MethodInfo.ReturnType != null) { action.Append(actionDescriptor.MethodInfo.ReturnType.Name + " "); } else { action.Append("void "); } action.Append(actionDescriptor.ControllerTypeInfo.FullName); action.Append("."); action.Append(actionDescriptor.MethodInfo.Name + "("); action.Append(string.Join(",", actionDescriptor.MethodInfo.GetParameters().Select(p => p.ParameterType.Name))); action.Append(")"); return(action.ToString()); }
/// <summary>判断控制器是否归属于魔方管辖</summary> /// <param name="controllerActionDescriptor"></param> /// <returns></returns> public static Boolean Contains(ControllerActionDescriptor controllerActionDescriptor) { // 判断控制器是否在管辖范围之内,不拦截其它控制器的异常信息 var controller = controllerActionDescriptor.ControllerTypeInfo; var ns = controller.Namespace; if (!ns.EndsWith(".Controllers")) { return(false); } if (_areas == null) { _areas = new HashSet <String>(Areas.Select(e => e.Namespace)); } // 该控制器父级命名空间必须有对应的区域注册类,才会拦截其异常 ns = ns.TrimEnd(".Controllers"); //return Areas.Any(e => e.Namespace == ns); return(_areas.Contains(ns)); }
private static ClientIdGetter GetSingleClientIdGetter(ControllerActionDescriptor controllerActionDescriptor) { if (controllerActionDescriptor.MethodInfo.GetCustomAttribute <SkipMarginTradingEnabledCheckAttribute>() != null) { return(null); } var clientIdGetters = GetClientIdGetters(controllerActionDescriptor.Parameters).ToList(); switch (clientIdGetters.Count) { case 0: return(null); case 1: return(clientIdGetters[0]); default: throw new InvalidOperationException("A controller action cannot have more then one ClientId in its parameters"); } }
static ControllerActionDescriptor Clone(ControllerActionDescriptor action, AttributeRouteInfo attributeRouteInfo) { var clone = new ControllerActionDescriptor() { ActionConstraints = action.ActionConstraints, ActionName = action.ActionName, AttributeRouteInfo = attributeRouteInfo, BoundProperties = action.BoundProperties, ControllerName = action.ControllerName, ControllerTypeInfo = action.ControllerTypeInfo, DisplayName = action.DisplayName, EndpointMetadata = action.EndpointMetadata, FilterDescriptors = action.FilterDescriptors, MethodInfo = action.MethodInfo, Parameters = action.Parameters, Properties = action.Properties, RouteValues = action.RouteValues, }; return(clone); }
public void BodyContentScraper_should_ignore_params_if_they_are_included_as_routing_constraints() { // arrange var routeInformation = new RouteInformation { RouteTemplate = "/api/{foo}/test", HttpMethod = "POST" }; // this will not run in asp.net core but just to be sure the package support 1 body param var description = new ControllerActionDescriptor { MethodInfo = typeof(FakeController).GetMethod("PostWithDuplicatedRouteAndBodyParam") }; // act BodyContentScraper.CompleteBodyRequiredContent(routeInformation, description); // assert Assert.Empty(routeInformation.BodyParams); }
private static void AddProperties( ControllerActionDescriptor actionDescriptor, ActionModel action, ControllerModel controller, ApplicationModel application) { foreach (var item in application.Properties) { actionDescriptor.Properties[item.Key] = item.Value; } foreach (var item in controller.Properties) { actionDescriptor.Properties[item.Key] = item.Value; } foreach (var item in action.Properties) { actionDescriptor.Properties[item.Key] = item.Value; } }
public override void OnActionExecuting(ActionExecutingContext actionContext) { string operationId = Convert.ToString(actionContext.RouteData.Values["action"]); if (!string.IsNullOrEmpty(operationId)) { actionContext.HttpContext.Response.Headers.Add("X-Operation-Id", operationId); } //// Add debug logs for each action call start ControllerActionDescriptor controllerActionDescriptor = actionContext.ActionDescriptor as ControllerActionDescriptor; actionContext.HttpContext.Items.Add(new KeyValuePair <object, object>("ActionRquestData", actionContext.ActionArguments)); actionContext.HttpContext.Items.Add(new KeyValuePair <object, object>("ControllerName", controllerActionDescriptor.ControllerName)); actionContext.HttpContext.Items.Add(new KeyValuePair <object, object>("ActionName", controllerActionDescriptor.ActionName)); if (!actionContext.ModelState.IsValid) { actionContext.Result = new ValidationFailedResult(actionContext.ModelState); } base.OnActionExecuting(actionContext); }
public void CreateController_ThrowsIfPropertyCannotBeActivated() { // Arrange var actionDescriptor = new ControllerActionDescriptor { ControllerTypeInfo = typeof(ControllerThatCannotBeActivated).GetTypeInfo() }; var services = GetServices(); var httpContext = new DefaultHttpContext { RequestServices = services }; var context = new ActionContext(httpContext, new RouteData(), actionDescriptor); var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache())); // Act and Assert var exception = Assert.Throws <InvalidOperationException>(() => factory.CreateController(context)); Assert.Equal("The property 'Service' on controller '" + typeof(ControllerThatCannotBeActivated) + "' cannot be activated.", exception.Message); }
/// <summary> /// 获取ActionModel /// </summary> /// <param name="actionDescriptor"></param> private static ActionModel GetActionModel(ControllerActionDescriptor actionDescriptor) { ActionModel action = new ActionModel() { Id = TypeHelper.GetMethodModuleMark(actionDescriptor.MethodInfo), AreaName = actionDescriptor.RouteValues.Keys.Contains("area") ? actionDescriptor.RouteValues["area"] : null, ControllerName = actionDescriptor.ControllerName, ActionName = actionDescriptor.ActionName, ActionFullName = actionDescriptor.DisplayName, RouteTemplate = actionDescriptor.AttributeRouteInfo?.Template, CustomAttrList = actionDescriptor.MethodInfo.CustomAttributes.Select((a, index) => GetCustomAttribute(a, index)).ToList(), InputParameters = actionDescriptor.Parameters.Select((a, index) => GetParam(((ControllerParameterDescriptor)a).ParameterInfo)).ToList(), ReturnParameter = GetParam(actionDescriptor.MethodInfo.ReturnParameter) }; return(action); }
/// <summary> /// Provides filters to apply to the specified action. /// </summary> /// <param name="context">The filter context.</param> public void OnProvidersExecuting(FilterProviderContext context) { if (context == null) { throw Error.ArgumentNull(nameof(context)); } // Actions with a bound parameter of type ODataQueryOptions do not support the query filter // The assumption is that the action will handle the querying within the action implementation ControllerActionDescriptor controllerActionDescriptor = context.ActionContext.ActionDescriptor as ControllerActionDescriptor; if (controllerActionDescriptor != null) { Type returnType = controllerActionDescriptor.MethodInfo.ReturnType; if (ShouldAddFilter(context, returnType, controllerActionDescriptor)) { var filterDesc = new FilterDescriptor(QueryFilter, FilterScope.Global); context.Results.Add(new FilterItem(filterDesc, QueryFilter)); } } }
public void GetControllerActionMethodExecutor_CachesExecutor() { // Arrange var services = CreateServices(); var cache = CreateCache(new DefaultFilterProvider()); var action = new ControllerActionDescriptor() { FilterDescriptors = new[] { new FilterDescriptor(new TestFilterFactory() { IsReusable = false }, FilterScope.Action), new FilterDescriptor(new TestFilter(), FilterScope.Action), }, MethodInfo = typeof(ControllerActionInvokerCache).GetMethod( nameof(ControllerActionInvokerCache.GetControllerActionMethodExecutor)), ControllerTypeInfo = typeof(ControllerActionInvokerCache).GetTypeInfo() }; var context = new ControllerContext( new ActionContext(new DefaultHttpContext(), new RouteData(), action)); // Act - 1 var executor1 = cache.GetControllerActionMethodExecutor(context); Assert.NotNull(executor1); var filters1 = cache.GetFilters(context); Assert.NotNull(filters1); // Act - 2 var executor2 = cache.GetControllerActionMethodExecutor(context); Assert.Same(executor1, executor2); }
public Func <ControllerContext, object> CreateControllerFactory(ControllerActionDescriptor descriptor) { if (descriptor == null) { throw new ArgumentNullException(nameof(descriptor)); } var controllerType = descriptor.ControllerTypeInfo?.AsType(); if (controllerType == null) { throw new ArgumentException(Resources.FormatPropertyOfTypeCannotBeNull( nameof(descriptor.ControllerTypeInfo), nameof(descriptor)), nameof(descriptor)); } if (_factoryCreateController != null) { return(_factoryCreateController); } var controllerActivator = _activatorProvider.CreateActivator(descriptor); var propertyActivators = GetPropertiesToActivate(descriptor); object CreateController(ControllerContext controllerContext) { var controller = controllerActivator(controllerContext); for (var i = 0; i < propertyActivators.Length; i++) { var propertyActivator = propertyActivators[i]; propertyActivator(controllerContext, controller); } return(controller); } return(CreateController); }
public async Task GetReturnsPublicCategoriesWhenUserNotAdministratorTest() { var claims = new List <Claim> { new Claim("sub", Guid.NewGuid().ToString()) }; var identity = new ClaimsIdentity(claims, "testing", "sub", "role"); var principal = new ClaimsPrincipal(identity); var categories = Model.Create <List <Category> >(); var query = Substitute.For <ICategoryQuery>(); var command = Substitute.For <ICategoryCommand>(); var httpContext = Substitute.For <HttpContext>(); var routerData = new RouteData(); var actionDescriptor = new ControllerActionDescriptor(); var actionContext = new ActionContext(httpContext, routerData, actionDescriptor); var controllerContext = new ControllerContext(actionContext); httpContext.User = principal; using (var tokenSource = new CancellationTokenSource()) { query.GetCategories(ReadType.VisibleOnly, tokenSource.Token).Returns(categories); using (var target = new CategoriesController(query, command)) { target.ControllerContext = controllerContext; var actual = await target.Get(tokenSource.Token).ConfigureAwait(false); actual.Should().BeOfType <OkObjectResult>(); var result = actual.As <OkObjectResult>(); var resultValues = result.Value as IEnumerable <PublicCategory>; resultValues.Should().BeEquivalentTo(categories, opt => opt.ExcludingMissingMembers()); } } }
private static bool IsActionAllowAnonymous(ControllerActionDescriptor controllerActionDescriptor) { // If action have any AllowAnonymousAttribute => Allow Anonymous bool isActionAllowAnonymous = controllerActionDescriptor.MethodInfo.GetCustomAttributes <AllowAnonymousAttribute>(true).Any(); if (isActionAllowAnonymous) { return(true); } var isActionHaveAnyPermission = controllerActionDescriptor.MethodInfo.GetCustomAttributes <AuthAttribute>(true).Any(); bool isCombineAuthorize = controllerActionDescriptor.MethodInfo.GetCustomAttributes <CombineAuthAttribute>(true).Any(); if (!isCombineAuthorize && isActionHaveAnyPermission) { return(false); } bool isControllerAllowAnonymous = controllerActionDescriptor.ControllerTypeInfo.GetCustomAttributes <AllowAnonymousAttribute>(true).Any(); if (isControllerAllowAnonymous) { return(true); } if (!isActionHaveAnyPermission) { var isControllerHaveAnyRole = controllerActionDescriptor.ControllerTypeInfo.GetCustomAttributes <AuthAttribute>(true).Any(); return(!isControllerHaveAnyRole); } return(false); }
protected internal IRouteDetails GetRouteDetails(ApiDescription desc) { var routeDetails = new AspNetCoreRouteDetails { HttpMethods = GetHttpMethods(desc) }; if (desc.ActionDescriptor.AttributeRouteInfo?.Template != null) { routeDetails.RouteTemplate = desc.ActionDescriptor.AttributeRouteInfo.Template; } else { ControllerActionDescriptor cdesc = desc.ActionDescriptor as ControllerActionDescriptor; routeDetails.RouteTemplate = $"/{cdesc.ControllerName}/{cdesc.ActionName}"; } List <string> produces = new List <string>(); foreach (var respTypes in desc.SupportedResponseTypes) { foreach (var format in respTypes.ApiResponseFormats) { produces.Add(format.MediaType); } } routeDetails.Produces = produces; List <string> consumes = new List <string>(); foreach (var reqTypes in desc.SupportedRequestFormats) { consumes.Add(reqTypes.MediaType); } routeDetails.Consumes = consumes; return(routeDetails); }
public async Task AttributeRouting_WithControllerActionDescriptor() { // Arrange var controllerType = typeof(HomeController); var actionMethod = controllerType.GetMethod("Index"); var action = new ControllerActionDescriptor(); action.DisplayName = "Microsoft.AspNet.Mvc.Routing.AttributeRoutingTest+HomeController.Index"; action.MethodInfo = actionMethod; action.RouteConstraints = new List <RouteDataActionConstraint>() { new RouteDataActionConstraint(AttributeRouting.RouteGroupKey, "group"), }; action.AttributeRouteInfo = new AttributeRouteInfo(); action.AttributeRouteInfo.Template = "{controller}/{action}"; action.RouteValueDefaults.Add("controller", "Home"); action.RouteValueDefaults.Add("action", "Index"); var expectedMessage = "The following errors occurred with attribute routing information:" + Environment.NewLine + Environment.NewLine + "For action: 'Microsoft.AspNet.Mvc.Routing.AttributeRoutingTest+HomeController.Index'" + Environment.NewLine + "Error: The attribute route '{controller}/{action}' cannot contain a parameter named '{controller}'. " + "Use '[controller]' in the route template to insert the value 'Home'."; var handler = CreateRouter(); var services = CreateServices(action); var route = AttributeRouting.CreateAttributeMegaRoute(handler, services); // Act & Assert var ex = await Assert.ThrowsAsync <InvalidOperationException>(async() => { await route.RouteAsync(new RouteContext(new DefaultHttpContext())); }); Assert.Equal(expectedMessage, ex.Message); }
public ControllerActionInvoker( [NotNull] ActionContext actionContext, [NotNull] IReadOnlyList <IFilterProvider> filterProviders, [NotNull] IControllerFactory controllerFactory, [NotNull] ControllerActionDescriptor descriptor, [NotNull] IReadOnlyList <IInputFormatter> inputFormatters, [NotNull] IReadOnlyList <IOutputFormatter> outputFormatters, [NotNull] IControllerActionArgumentBinder controllerActionArgumentBinder, [NotNull] IReadOnlyList <IModelBinder> modelBinders, [NotNull] IReadOnlyList <IModelValidatorProvider> modelValidatorProviders, [NotNull] IReadOnlyList <IValueProviderFactory> valueProviderFactories, [NotNull] IScopedInstance <ActionBindingContext> actionBindingContextAccessor, [NotNull] ITempDataDictionary tempData, [NotNull] ILoggerFactory loggerFactory, int maxModelValidationErrors) : base( actionContext, filterProviders, inputFormatters, outputFormatters, modelBinders, modelValidatorProviders, valueProviderFactories, actionBindingContextAccessor, loggerFactory, maxModelValidationErrors) { _descriptor = descriptor; _controllerFactory = controllerFactory; _argumentBinder = controllerActionArgumentBinder; _tempData = tempData; if (descriptor.MethodInfo == null) { throw new ArgumentException( Resources.FormatPropertyOfTypeCannotBeNull("MethodInfo", typeof(ControllerActionDescriptor)), "descriptor"); } }
private static string CreateMixedRoutedActionDescriptorsErrorMessage( ControllerActionDescriptor actionDescriptor, IDictionary <ActionModel, IList <ControllerActionDescriptor> > actionsForMethod) { // Text to show as the attribute route template for conventionally routed actions. var nullTemplate = Resources.AttributeRoute_NullTemplateRepresentation; var actionDescriptions = new List <string>(); foreach (var action in actionsForMethod.SelectMany(kvp => kvp.Value)) { var routeTemplate = action.AttributeRouteInfo?.Template ?? nullTemplate; var verbs = action.ActionConstraints.OfType <HttpMethodActionConstraint>().FirstOrDefault()?.HttpMethods; var formattedVerbs = string.Join(", ", verbs.OrderBy(v => v, StringComparer.Ordinal)); var description = Resources.FormatAttributeRoute_MixedAttributeAndConventionallyRoutedActions_ForMethod_Item( action.DisplayName, routeTemplate, formattedVerbs); actionDescriptions.Add(description); } // Sample error message: // // A method 'MyApplication.CustomerController.Index' must not define attributed actions and // non attributed actions at the same time: // Action: 'MyApplication.CustomerController.Index' - Route Template: 'Products' - HTTP Verbs: 'PUT' // Action: 'MyApplication.CustomerController.Index' - Route Template: '(none)' - HTTP Verbs: 'POST' // // Use 'AcceptVerbsAttribute' to create a single route that allows multiple HTTP verbs and defines a route, // or set a route template in all attributes that constrain HTTP verbs. return (Resources.FormatAttributeRoute_MixedAttributeAndConventionallyRoutedActions_ForMethod( actionDescriptor.DisplayName, Environment.NewLine, string.Join(Environment.NewLine, actionDescriptions))); }
public ControllerActionInvoker( [NotNull] ActionContext actionContext, [NotNull] IReadOnlyList<IFilterProvider> filterProviders, [NotNull] IControllerFactory controllerFactory, [NotNull] ControllerActionDescriptor descriptor, [NotNull] IReadOnlyList<IInputFormatter> inputFormatters, [NotNull] IReadOnlyList<IOutputFormatter> outputFormatters, [NotNull] IControllerActionArgumentBinder controllerActionArgumentBinder, [NotNull] IReadOnlyList<IModelBinder> modelBinders, [NotNull] IReadOnlyList<IModelValidatorProvider> modelValidatorProviders, [NotNull] IReadOnlyList<IValueProviderFactory> valueProviderFactories, [NotNull] IActionBindingContextAccessor actionBindingContextAccessor, [NotNull] ILogger logger, [NotNull] INotifier notifier, int maxModelValidationErrors) : base( actionContext, filterProviders, inputFormatters, outputFormatters, modelBinders, modelValidatorProviders, valueProviderFactories, actionBindingContextAccessor, logger, notifier, maxModelValidationErrors) { _descriptor = descriptor; _controllerFactory = controllerFactory; _argumentBinder = controllerActionArgumentBinder; if (descriptor.MethodInfo == null) { throw new ArgumentException( Resources.FormatPropertyOfTypeCannotBeNull("MethodInfo", typeof(ControllerActionDescriptor)), "descriptor"); } }
/// <summary> /// Initializes a new instance of the WebApiActionDescriptor class. /// </summary> /// <param name="actionDescriptor">The inner descriptor.</param> public WebApiActionDescriptor(ControllerActionDescriptor actionDescriptor) { if (actionDescriptor == null) { throw Error.ArgumentNull("actionDescriptor"); } this.innerDescriptor = actionDescriptor; this.supportedHttpMethods = new List <ODataRequestMethod>(); // Determine the supported methods. IEnumerable <string> actionMethods = null; /*actionDescriptor.ActionConstraints? * .OfType<HttpMethodActionConstraint>() * .FirstOrDefault()? * .HttpMethods; */ if (actionMethods == null) { // If no HttpMethodActionConstraint is specified, fall back to convention the way AspNet does. actionMethods = SupportedHttpMethodConventions .Where(method => actionDescriptor.MethodInfo.Name.StartsWith(method, StringComparison.OrdinalIgnoreCase)); // Use POST as the default method. if (!actionMethods.Any()) { actionMethods = new string[] { "POST" }; } } foreach (string method in actionMethods) { bool ignoreCase = true; ODataRequestMethod methodEnum = ODataRequestMethod.Unknown; if (Enum.TryParse <ODataRequestMethod>(method, ignoreCase, out methodEnum)) { this.supportedHttpMethods.Add(methodEnum); } } }
private string GetOperationId(OpenApiDocument document, ControllerActionDescriptor actionDescriptor, MethodInfo method) { string operationId; dynamic swaggerOperationAttribute = method .GetCustomAttributes() .FirstAssignableToTypeNameOrDefault("SwaggerOperationAttribute", TypeNameStyle.Name); if (swaggerOperationAttribute != null && !string.IsNullOrEmpty(swaggerOperationAttribute.OperationId)) { operationId = swaggerOperationAttribute.OperationId; } else if (Settings.UseRouteNameAsOperationId && !string.IsNullOrEmpty(actionDescriptor.AttributeRouteInfo.Name)) { operationId = actionDescriptor.AttributeRouteInfo.Name; } else { dynamic openApiControllerAttribute = actionDescriptor .ControllerTypeInfo? .GetCustomAttributes()? .FirstAssignableToTypeNameOrDefault("OpenApiControllerAttribute", TypeNameStyle.Name); var controllerName = openApiControllerAttribute != null && !string.IsNullOrEmpty(openApiControllerAttribute.Name) ? openApiControllerAttribute.Name : actionDescriptor.ControllerName; operationId = controllerName + "_" + GetActionName(actionDescriptor.ActionName); } var number = 1; while (document.Operations.Any(o => o.Operation.OperationId == operationId + (number > 1 ? "_" + number : string.Empty))) { number++; } return(operationId + (number > 1 ? number.ToString() : string.Empty)); }
public void OnAuthorization(AuthorizationFilterContext filterContext) { ////验证是否是登录用户 ControllerActionDescriptor actionDescriptor = null; var identity = filterContext.HttpContext.User.Identity; if (identity.IsAuthenticated) { actionDescriptor = (ControllerActionDescriptor)filterContext.ActionDescriptor; var controllerName = actionDescriptor.ControllerName; var actionName = actionDescriptor.ActionName; //验证用户操作是否在权限列表中 if (HasActionQulification(actionName, controllerName, identity.Name)) { if (string.IsNullOrEmpty(UserLoginTicket)) { //用户的Session, Cookie都过期,需要重新登录 filterContext.HttpContext.Response.Redirect("~/Account/Login", false); } else { //虽然是登录用户,但没有该Action的权限,跳转到“未授权访问”页面 filterContext.HttpContext.Response.Redirect("~/Home/UnAuthorized", true); } } } else { //未登录用户,则判断是否是匿名访问 var actionAttributes = actionDescriptor.MethodInfo.GetCustomAttributes(inherit: true); bool isAnonymous = actionAttributes.Any(a => a is AllowAnonymousFilter); if (!isAnonymous) { //未验证(登录)的用户, 而且是非匿名访问,则转向登录页面 filterContext.HttpContext.Response.Redirect("~/Account/Login", true); } } }
private ControllerActionDescriptor CreateActionDescriptor( string httpMethod, string routeTemplate, string actionFixtureName) { var descriptor = new ControllerActionDescriptor(); descriptor.SetProperty(new ApiDescriptionActionData()); descriptor.DisplayName = actionFixtureName; descriptor.ActionConstraints = new List <IActionConstraintMetadata> { new HttpMethodConstraint(new[] { httpMethod }) }; descriptor.AttributeRouteInfo = new AttributeRouteInfo { Template = routeTemplate }; descriptor.MethodInfo = typeof(ActionFixtures).GetMethod(actionFixtureName); if (descriptor.MethodInfo == null) { throw new InvalidOperationException( string.Format("{0} is not declared in ActionFixtures", actionFixtureName)); } descriptor.Parameters = descriptor.MethodInfo.GetParameters() .Select(paramInfo => new ParameterDescriptor { Name = paramInfo.Name, ParameterType = paramInfo.ParameterType, BindingInfo = BindingInfo.GetBindingInfo(paramInfo.GetCustomAttributes(false)) }) .ToList(); // Set some additional properties - typically done via IApplicationModelConvention var attributes = descriptor.MethodInfo.GetCustomAttributes(true); descriptor.Properties.Add("ActionAttributes", attributes); descriptor.Properties.Add("IsObsolete", attributes.OfType <ObsoleteAttribute>().Any()); return(descriptor); }
public void TransformAsyncReturnsCorrectRouteValues() { // Arrange IEndpointRouteBuilder builder = EndpointRouteBuilderFactory.Create("odata", c => c.AddService(ServiceLifetime.Singleton, b => GetEdmModel())); HttpContext httpContext = new DefaultHttpContext { RequestServices = builder.ServiceProvider }; HttpRequest request = SetHttpRequest(httpContext, HttpMethod.Get, "http://localhost:123/Customers(1)"); RouteValueDictionary values = new RouteValueDictionary(); values.Add("ODataEndpointPath_odata", "Customers(1)"); ActionDescriptor actionDescriptor = new ControllerActionDescriptor { ControllerName = "Customers", ActionName = "Get" }; IActionSelector actionSelector = new MockActionSelector(actionDescriptor); // Act ODataEndpointRouteValueTransformer transformer = new ODataEndpointRouteValueTransformer(actionSelector); ValueTask <RouteValueDictionary> actual = transformer.TransformAsync(httpContext, values); // Assert Assert.NotNull(actual.Result); RouteValueDictionary routeValues = actual.Result; Assert.Equal(4, routeValues.Count); Assert.Equal("Customers(1)", routeValues["ODataEndpointPath_odata"]); Assert.Equal("Customers", routeValues["controller"]); Assert.Equal("Get", routeValues["action"]); Assert.Equal("Customers(1)", routeValues["odataPath"]); Assert.NotNull(httpContext.ODataFeature().Path); Assert.Same(actionDescriptor, httpContext.ODataFeature().ActionDescriptor); }
public static void AddRouteValues( ControllerActionDescriptor actionDescriptor, ControllerModel controller, ActionModel action) { // Apply all the constraints defined on the action, then controller (for example, [Area]) // to the actions. Also keep track of all the constraints that require preventing actions // without the constraint to match. For example, actions without an [Area] attribute on their // controller should not match when a value has been given for area when matching a url or // generating a link. foreach (var kvp in action.RouteValues) { // Skip duplicates if (!actionDescriptor.RouteValues.ContainsKey(kvp.Key)) { actionDescriptor.RouteValues.Add(kvp.Key, kvp.Value); } } foreach (var kvp in controller.RouteValues) { // Skip duplicates - this also means that a value on the action will take precedence if (!actionDescriptor.RouteValues.ContainsKey(kvp.Key)) { actionDescriptor.RouteValues.Add(kvp.Key, kvp.Value); } } // Lastly add the 'default' values if (!actionDescriptor.RouteValues.ContainsKey("action")) { actionDescriptor.RouteValues.Add("action", action.ActionName ?? string.Empty); } if (!actionDescriptor.RouteValues.ContainsKey("controller")) { actionDescriptor.RouteValues.Add("controller", controller.ControllerName); } }
private List <string> getAuthTypes(ControllerActionDescriptor ad) { var authenticationSchemes = new List <string>(); if (ad.MethodInfo.IsDefined(typeof(AuthorizeAttribute), false)) { var authorizeAttr = ad.MethodInfo.GetCustomAttributes(typeof(AuthorizeAttribute), false).FirstOrDefault() as AuthorizeAttribute; if (authorizeAttr != null) { authenticationSchemes = authorizeAttr.AuthenticationSchemes.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); } } else if (ad.ControllerTypeInfo.IsDefined(typeof(AuthorizeAttribute), false)) { var authorizeAttr = ad.ControllerTypeInfo.GetCustomAttributes(typeof(AuthorizeAttribute), false).FirstOrDefault() as AuthorizeAttribute; if (authorizeAttr != null) { authenticationSchemes = authorizeAttr.AuthenticationSchemes.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); } } return(authenticationSchemes); }
private IDictionary <string, object> GetActionParameters(ControllerActionDescriptor actionDescriptor, IDictionary <string, object> actionArguments, bool serializeParams) { var args = actionArguments.ToDictionary(k => k.Key, v => v.Value); foreach (var param in actionDescriptor.Parameters) { var paramDescriptor = param as ControllerParameterDescriptor; if (paramDescriptor?.ParameterInfo.GetCustomAttribute <AuditIgnoreAttribute>(true) != null) { args.Remove(param.Name); } else if (paramDescriptor?.ParameterInfo.GetCustomAttribute <FromServicesAttribute>(true) != null) { args.Remove(param.Name); } } if (serializeParams) { return(AuditApiHelper.SerializeParameters(args)); } return(args); }
private ControllerActionDescriptor CreateActionDescriptor( string httpMethod, string routeTemplate, string actionFixtureName, string controllerFixtureName ) { var descriptor = new ControllerActionDescriptor(); descriptor.SetProperty(new ApiDescriptionActionData()); descriptor.DisplayName = actionFixtureName; descriptor.ActionConstraints = new List<IActionConstraintMetadata>(); if (httpMethod != null) descriptor.ActionConstraints.Add(new HttpMethodConstraint(new[] { httpMethod })); descriptor.AttributeRouteInfo = new AttributeRouteInfo { Template = routeTemplate }; descriptor.MethodInfo = typeof(ActionFixtures).GetMethod(actionFixtureName); if (descriptor.MethodInfo == null) throw new InvalidOperationException( string.Format("{0} is not declared in ActionFixtures", actionFixtureName)); descriptor.Parameters = descriptor.MethodInfo.GetParameters() .Select(paramInfo => new ParameterDescriptor { Name = paramInfo.Name, ParameterType = paramInfo.ParameterType, BindingInfo = BindingInfo.GetBindingInfo(paramInfo.GetCustomAttributes(false)) }) .ToList(); var controllerType = typeof(ControllerFixtures).GetNestedType(controllerFixtureName); if (controllerType == null) throw new InvalidOperationException( string.Format("{0} is not declared in ControllerFixtures", controllerFixtureName)); descriptor.ControllerTypeInfo = controllerType.GetTypeInfo(); return descriptor; }
public void CreateController_SetsPropertiesFromActionContextHierarchy() { // Arrange var actionDescriptor = new ControllerActionDescriptor { ControllerTypeInfo = typeof(ControllerWithActivateAndFromServices).GetTypeInfo() }; var services = GetServices(); var httpContext = new DefaultHttpContext { RequestServices = services }; var context = new ActionContext(httpContext, new RouteData(), actionDescriptor); var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache())); // Act var result = factory.CreateController(context); // Assert var controller = Assert.IsType<ControllerWithActivateAndFromServices>(result); Assert.Same(context, controller.ActionContext); Assert.Same(httpContext, controller.HttpContext); }
public void CreateController_ThrowsIfPropertyCannotBeActivated() { // Arrange var actionDescriptor = new ControllerActionDescriptor { ControllerTypeInfo = typeof(ControllerThatCannotBeActivated).GetTypeInfo() }; var services = GetServices(); var httpContext = new DefaultHttpContext { RequestServices = services }; var context = new ActionContext(httpContext, new RouteData(), actionDescriptor); var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache())); // Act and Assert var exception = Assert.Throws<InvalidOperationException>(() => factory.CreateController(context)); Assert.Equal("The property 'Service' on controller '" + typeof(ControllerThatCannotBeActivated) + "' cannot be activated.", exception.Message); }
public void CreateController_SetsBindingContext() { // Arrange var actionDescriptor = new ControllerActionDescriptor { ControllerTypeInfo = typeof(ControllerWithActivateAndFromServices).GetTypeInfo() }; var bindingContext = new ActionBindingContext(); var services = GetServices(); services.GetRequiredService<IScopedInstance<ActionBindingContext>>().Value = bindingContext; var httpContext = new DefaultHttpContext { RequestServices = services }; var context = new ActionContext(httpContext, new RouteData(), actionDescriptor); var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache())); // Act var result = factory.CreateController(context); // Assert var controller = Assert.IsType<ControllerWithActivateAndFromServices>(result); Assert.Same(bindingContext, controller.BindingContext); }
private ControllerActionDescriptor CreateActionDescriptor(string methodName = null, Type controllerType = null) { var action = new ControllerActionDescriptor(); action.SetProperty(new ApiDescriptionActionData()); if (controllerType != null) { action.MethodInfo = controllerType.GetMethod( methodName ?? "ReturnsObject", BindingFlags.Instance | BindingFlags.Public); action.ControllerTypeInfo = controllerType.GetTypeInfo(); action.BoundProperties = new List<ParameterDescriptor>(); foreach (var property in action.ControllerTypeInfo.GetProperties()) { var bindingInfo = BindingInfo.GetBindingInfo(property.GetCustomAttributes().OfType<object>()); if (bindingInfo != null) { action.BoundProperties.Add(new ParameterDescriptor() { BindingInfo = bindingInfo, Name = property.Name, ParameterType = property.PropertyType, }); } } } else { action.MethodInfo = GetType().GetMethod( methodName ?? "ReturnsObject", BindingFlags.Instance | BindingFlags.NonPublic); } action.Parameters = new List<ParameterDescriptor>(); foreach (var parameter in action.MethodInfo.GetParameters()) { action.Parameters.Add(new ParameterDescriptor() { Name = parameter.Name, ParameterType = parameter.ParameterType, BindingInfo = BindingInfo.GetBindingInfo(parameter.GetCustomAttributes().OfType<object>()) }); } return action; }
public void AttributeRouting_WithControllerActionDescriptor() { // Arrange var controllerType = typeof(HomeController); var actionMethod = controllerType.GetMethod("Index"); var action = new ControllerActionDescriptor(); action.DisplayName = "Microsoft.AspNet.Mvc.Routing.AttributeRoutingTest+HomeController.Index"; action.MethodInfo = actionMethod; action.RouteConstraints = new List<RouteDataActionConstraint>() { new RouteDataActionConstraint(AttributeRouting.RouteGroupKey, "group"), }; action.AttributeRouteInfo = new AttributeRouteInfo(); action.AttributeRouteInfo.Template = "{controller}/{action}"; action.RouteValueDefaults.Add("controller", "Home"); action.RouteValueDefaults.Add("action", "Index"); var expectedMessage = "The following errors occurred with attribute routing information:" + Environment.NewLine + Environment.NewLine + "For action: 'Microsoft.AspNet.Mvc.Routing.AttributeRoutingTest+HomeController.Index'" + Environment.NewLine + "Error: The attribute route '{controller}/{action}' cannot contain a parameter named '{controller}'. " + "Use '[controller]' in the route template to insert the value 'Home'."; var handler = CreateRouter(); var services = CreateServices(action); // Act & Assert var ex = Assert.Throws<InvalidOperationException>(() => { AttributeRouting.CreateAttributeMegaRoute(handler, services); }); Assert.Equal(expectedMessage, ex.Message); }
public void CreateController_IgnoresPropertiesThatAreNotDecoratedWithActivateAttribute() { // Arrange var actionDescriptor = new ControllerActionDescriptor { ControllerTypeInfo = typeof(ControllerWithActivateAndFromServices).GetTypeInfo() }; var services = GetServices(); var httpContext = new DefaultHttpContext { RequestServices = services }; var context = new ActionContext(httpContext, new RouteData(), actionDescriptor); var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache())); // Act var result = factory.CreateController(context); // Assert var controller = Assert.IsType<ControllerWithActivateAndFromServices>(result); Assert.Null(controller.Response); }
public void ControllerContextSetter_CanBeUsedWithControllerActionContext() { // Arrange var actionDescriptor = new ControllerActionDescriptor(); var httpContext = new DefaultHttpContext(); var routeData = new RouteData(); var controllerContext = new ControllerContext() { ActionDescriptor = actionDescriptor, HttpContext = httpContext, RouteData = routeData, }; var controller = new TestabilityController(); // Act controller.ControllerContext = controllerContext; // Assert Assert.Same(httpContext, controller.HttpContext); Assert.Same(routeData, controller.RouteData); Assert.Equal(controllerContext.ModelState, controller.ModelState); Assert.Same(actionDescriptor, controllerContext.ActionDescriptor); }