Esempio n. 1
0
 private static void RegisterAutomaticRoutes(
     RouteCollection routeCollection,
     IInlineConstraintResolver constraintResolver)
 {
     var controllerAssembly = typeof(WikiController).Assembly;
     routeCollection.MapMvcAttributeRoutes(controllerAssembly, constraintResolver);
 }
Esempio n. 2
0
        public TemplateRoute(
            IRouter target,
            string routeName,
            string routeTemplate,
            IDictionary <string, object> defaults,
            IDictionary <string, object> constraints,
            IDictionary <string, object> dataTokens,
            IInlineConstraintResolver inlineConstraintResolver)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            _target        = target;
            _routeTemplate = routeTemplate ?? string.Empty;
            Name           = routeName;

            _dataTokens = dataTokens == null ? RouteValueDictionary.Empty : new RouteValueDictionary(dataTokens);

            // Data we parse from the template will be used to fill in the rest of the constraints or
            // defaults. The parser will throw for invalid routes.
            _parsedTemplate = TemplateParser.Parse(RouteTemplate);

            _constraints = GetConstraints(inlineConstraintResolver, RouteTemplate, _parsedTemplate, constraints);
            _defaults    = GetDefaults(_parsedTemplate, defaults);

            _matcher = new TemplateMatcher(_parsedTemplate, Defaults);
            _binder  = new TemplateBinder(_parsedTemplate, Defaults);
        }
Esempio n. 3
0
 public SubDomainRouter(
     IRouter target,
     string subDomain,//当前路由规则绑定的二级域名
     string routeTemplate,
     RouteValueDictionary defaults,
     RouteValueDictionary constrains,
     IInlineConstraintResolver inlineConstraintResolver)
     : base(routeTemplate,
            subDomain,
            inlineConstraintResolver,
            defaults,
            constrains,
            new RouteValueDictionary(null))
 {
     if (target == null)
     {
         throw new ArgumentNullException(nameof(target));
     }
     if (subDomain == null)
     {
         throw new ArgumentNullException(nameof(subDomain));
     }
     _subDomain = subDomain;
     _target    = target;
 }
        public async Task <IActionResult> SetupMethod([FromBody] SetupMethodBinding binding,
                                                      [FromServices] IInlineConstraintResolver inlineConstraintResolver,
                                                      CancellationToken cancellationToken)
        {
            _routeCollection.MapVerb(
                inlineConstraintResolver: inlineConstraintResolver,
                verb: binding.Method,
                template: binding.Route,
                handler: async(req, res, rdata) =>
            {
                res.StatusCode = binding.Response.HttpCode;

                if (binding.Response.Headers != null)
                {
                    foreach (var kvp in binding.Response.Headers)
                    {
                        res.Headers.Add(kvp.Key, kvp.Value);
                    }
                }

                await res.Body.WriteAsync(Encoding.UTF8.GetBytes(binding.Response.Body));
            });

            return(NoContent());
        }
Esempio n. 5
0
        private static IRouteConstraint GetInlineConstraint(Group constraintGroup,
                                                            IInlineConstraintResolver _constraintResolver)
        {
            var parameterConstraints = new List <IRouteConstraint>();

            foreach (Capture constraintCapture in constraintGroup.Captures)
            {
                var inlineConstraint = constraintCapture.Value;
                var constraint       = _constraintResolver.ResolveConstraint(inlineConstraint);
                if (constraint == null)
                {
                    throw new InvalidOperationException(
                              Resources.FormatInlineRouteParser_CouldNotResolveConstraint(
                                  _constraintResolver.GetType().Name, inlineConstraint));
                }

                parameterConstraints.Add(constraint);
            }

            if (parameterConstraints.Count > 0)
            {
                var constraint = parameterConstraints.Count == 1 ?
                                 parameterConstraints[0] :
                                 new CompositeRouteConstraint(parameterConstraints);
                return(constraint);
            }

            return(null);
        }
        /// <summary>
        /// Maps the attribute-defined routes for the application.
        /// </summary>
        /// <param name="configuration">The server configuration.</param>
        /// <param name="constraintResolver">The <see cref="IInlineConstraintResolver"/> to use for resolving inline constraints.</param>
        public static void MapHttpAttributeRoutes(this HttpConfiguration configuration, IInlineConstraintResolver constraintResolver)
        {
            HttpRouteBuilder routeBuilder = new HttpRouteBuilder(constraintResolver);
            var attrRoute = new RouteCollectionRoute();
            configuration.Routes.Add(AttributeRouteName, attrRoute);

            Action<HttpConfiguration> previousInitializer = configuration.Initializer;
            configuration.Initializer = config =>
                {
                    // Chain to the previous initializer hook. Do this before we access the config since
                    // initialization may make last minute changes to the configuration.
                    previousInitializer(config);

                    // Add a single placeholder route that handles all of attribute routing.
                    // Add an initialize hook that initializes these routes after the config has been initialized.
                    Func<HttpSubRouteCollection> initializer = () => MapHttpAttributeRoutesInternal(configuration, routeBuilder);

                    // This won't change config. It wants to pick up the finalized config.
                    HttpSubRouteCollection subRoutes = attrRoute.EnsureInitialized(initializer);
                    if (subRoutes != null)
                    {
                        AddGenerationHooksForSubRoutes(config.Routes, subRoutes, routeBuilder);
                    }
                };
        }
Esempio n. 7
0
 public GenericRoute(IRouter target, string routeName, string routeTemplate, RouteValueDictionary defaults,
                     IDictionary <string, object> constraints,
                     RouteValueDictionary dataTokens, IInlineConstraintResolver inlineConstraintResolver)
     : base(target, routeName, routeTemplate, defaults, constraints, dataTokens, inlineConstraintResolver)
 {
     _target = target ?? throw new ArgumentNullException(nameof(target));
 }
Esempio n. 8
0
        public RouteBase(
            string template,
            string name,
            IInlineConstraintResolver constraintResolver,
            RouteValueDictionary defaults,
            IDictionary <string, object> constraints,
            RouteValueDictionary dataTokens)
        {
            if (constraintResolver == null)
            {
                throw new ArgumentNullException(nameof(constraintResolver));
            }

            template           = template ?? string.Empty;
            Name               = name;
            ConstraintResolver = constraintResolver;
            DataTokens         = dataTokens ?? new RouteValueDictionary();

            try
            {
                // Data we parse from the template will be used to fill in the rest of the constraints or
                // defaults. The parser will throw for invalid routes.
                ParsedTemplate = TemplateParser.Parse(template);

                Constraints = GetConstraints(constraintResolver, ParsedTemplate, constraints);
                Defaults    = GetDefaults(ParsedTemplate, defaults);
            }
            catch (Exception exception)
            {
                throw new RouteCreationException($"An error occurred while creating the route with name '{name}' and template '{template}'.", exception);
            }
        }
 public SubDomainRoute(string[] hostnames, string subdomain, IRouter target, string routeName, string routeTemplate, RouteValueDictionary defaults, IDictionary <string, object> constraints,
                       RouteValueDictionary dataTokens, IInlineConstraintResolver inlineConstraintResolver)
     : base(target, routeName, routeTemplate, defaults, constraints, dataTokens, inlineConstraintResolver)
 {
     Hostnames = hostnames;
     Subdomain = subdomain;
 }
Esempio n. 10
0
        public TreeRouteBuilder(
            ILoggerFactory loggerFactory,
#pragma warning disable CS0618, PUB0001 // Type or member is obsolete
            ObjectPool <UriBuildingContext> objectPool,
#pragma warning restore CS0618, PUB0001 // Type or member is obsolete
            IInlineConstraintResolver constraintResolver)
        {
            if (loggerFactory == null)
            {
                throw new ArgumentNullException(nameof(loggerFactory));
            }

            if (objectPool == null)
            {
                throw new ArgumentNullException(nameof(objectPool));
            }

            if (constraintResolver == null)
            {
                throw new ArgumentNullException(nameof(constraintResolver));
            }

            _urlEncoder         = UrlEncoder.Default;
            _objectPool         = objectPool;
            _constraintResolver = constraintResolver;

            _logger           = loggerFactory.CreateLogger <TreeRouter>();
            _constraintLogger = loggerFactory.CreateLogger(typeof(RouteConstraintMatcher).FullName);
        }
Esempio n. 11
0
        public TemplateRoute(
            IRouter target,
            string routeName,
            string routeTemplate,
            IDictionary<string, object> defaults,
            IDictionary<string, object> constraints,
            IDictionary<string, object> dataTokens,
            IInlineConstraintResolver inlineConstraintResolver)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            _target = target;
            _routeTemplate = routeTemplate ?? string.Empty;
            Name = routeName;

            _dataTokens = dataTokens == null ? RouteValueDictionary.Empty : new RouteValueDictionary(dataTokens);

            // Data we parse from the template will be used to fill in the rest of the constraints or
            // defaults. The parser will throw for invalid routes.
            _parsedTemplate = TemplateParser.Parse(RouteTemplate);

            _constraints = GetConstraints(inlineConstraintResolver, RouteTemplate, _parsedTemplate, constraints);
            _defaults = GetDefaults(_parsedTemplate, defaults);

            _matcher = new TemplateMatcher(_parsedTemplate, Defaults);
            _binder = new TemplateBinder(_parsedTemplate, Defaults);
        }
Esempio n. 12
0
        public AttributeRoute(
            IRouter target,
            IActionDescriptorsCollectionProvider actionDescriptorsCollectionProvider,
            IInlineConstraintResolver constraintResolver,
            ILoggerFactory loggerFactory)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            if (actionDescriptorsCollectionProvider == null)
            {
                throw new ArgumentNullException(nameof(actionDescriptorsCollectionProvider));
            }

            if (constraintResolver == null)
            {
                throw new ArgumentNullException(nameof(constraintResolver));
            }

            if (loggerFactory == null)
            {
                throw new ArgumentNullException(nameof(loggerFactory));
            }

            _target = target;
            _actionDescriptorsCollectionProvider = actionDescriptorsCollectionProvider;
            _constraintResolver = constraintResolver;

            _routeLogger = loggerFactory.CreateLogger<InnerAttributeRoute>();
            _constraintLogger = loggerFactory.CreateLogger(typeof(RouteConstraintMatcher).FullName);
        }
Esempio n. 13
0
        public static IRouteBuilder MapGreedyContentRoute(
            this IRouteBuilder routeBuilder,
            string name,
            string templatePrefix,
            object defaults,
            object constraints = null,
            object dataTokens  = null)
        {
            IInlineConstraintResolver requiredService   = routeBuilder.ServiceProvider.GetRequiredService <IInlineConstraintResolver>();
            IControllerMapper         controllerMapper  = routeBuilder.ServiceProvider.GetRequiredService <IControllerMapper>();
            ITargetingFilterAccessor  targetingAccessor = routeBuilder.ServiceProvider.GetService <ITargetingFilterAccessor>();
            IHeadUrlResolver          headUrlResolver   = routeBuilder.ServiceProvider.GetService <IHeadUrlResolver>();

            var template        = CreateRouteTemplate(templatePrefix);
            var constraintsDict = ObjectToDictionary(constraints);

            constraintsDict.Add(TailRouteTokenName, new GreedyRouteConstraint(TailRouteTokenName));

            var route = new GreedyContentRoute(controllerMapper, targetingAccessor, headUrlResolver,
                                               routeBuilder.DefaultHandler,
                                               name,
                                               template,
                                               new RouteValueDictionary(defaults),
                                               constraintsDict,
                                               new RouteValueDictionary(dataTokens),
                                               requiredService);

            routeBuilder.Routes.Add(route);

            return(routeBuilder);
        }
Esempio n. 14
0
        public TreeMatcher(
            IInlineConstraintResolver constraintFactory,
            ILogger logger,
            EndpointDataSource dataSource)
        {
            if (constraintFactory == null)
            {
                throw new ArgumentNullException(nameof(constraintFactory));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            if (dataSource == null)
            {
                throw new ArgumentNullException(nameof(dataSource));
            }

            _constraintFactory = constraintFactory;
            _logger            = logger;
            _cache             = new DataSourceDependantCache <UrlMatchingTree[]>(dataSource, CreateTrees);
            _cache.EnsureInitialized();
        }
Esempio n. 15
0
        public MvcEndpointInfo(
            string name,
            string template,
            RouteValueDictionary defaults,
            IDictionary <string, object> constraints,
            RouteValueDictionary dataTokens,
            IInlineConstraintResolver constraintResolver)
        {
            Name       = name;
            Template   = template ?? string.Empty;
            DataTokens = dataTokens;

            try
            {
                // Data we parse from the template will be used to fill in the rest of the constraints or
                // defaults. The parser will throw for invalid routes.
                ParsedTemplate = TemplateParser.Parse(template);

                Constraints    = GetConstraints(constraintResolver, ParsedTemplate, constraints);
                Defaults       = defaults;
                MergedDefaults = GetDefaults(ParsedTemplate, defaults);
            }
            catch (Exception exception)
            {
                throw new RouteCreationException(
                          string.Format(CultureInfo.CurrentCulture, "An error occurred while creating the route with name '{0}' and template '{1}'.", name, template), exception);
            }
        }
        private static Route CreateTemplateRoute(
            string template,
            string routerName = null,
            RouteValueDictionary dataTokens = null,
            IInlineConstraintResolver constraintResolver = null)
        {
            var target = new Mock <IRouter>(MockBehavior.Strict);

            target
            .Setup(e => e.GetVirtualPath(It.IsAny <VirtualPathContext>()))
            .Returns <VirtualPathContext>(rc => null);

            if (constraintResolver == null)
            {
                constraintResolver = new Mock <IInlineConstraintResolver>().Object;
            }

            return(new Route(
                       target.Object,
                       routerName,
                       template,
                       defaults: null,
                       constraints: null,
                       dataTokens: dataTokens,
                       inlineConstraintResolver: constraintResolver));
        }
Esempio n. 17
0
    /// <summary>
    /// Creates a new <see cref="RouteBase"/> instance.
    /// </summary>
    /// <param name="template">The route template.</param>
    /// <param name="name">The name of the route.</param>
    /// <param name="constraintResolver">An <see cref="IInlineConstraintResolver"/> used for resolving inline constraints.</param>
    /// <param name="defaults">The default values for parameters in the route.</param>
    /// <param name="constraints">The constraints for the route.</param>
    /// <param name="dataTokens">The data tokens for the route.</param>
    public RouteBase(
        string?template,
        string?name,
        IInlineConstraintResolver constraintResolver,
        RouteValueDictionary?defaults,
        IDictionary <string, object>?constraints,
        RouteValueDictionary?dataTokens)
    {
        if (constraintResolver == null)
        {
            throw new ArgumentNullException(nameof(constraintResolver));
        }

        template           = template ?? string.Empty;
        Name               = name;
        ConstraintResolver = constraintResolver;
        DataTokens         = dataTokens ?? new RouteValueDictionary();

        try
        {
            // Data we parse from the template will be used to fill in the rest of the constraints or
            // defaults. The parser will throw for invalid routes.
            ParsedTemplate = TemplateParser.Parse(template);

            Constraints = GetConstraints(constraintResolver, ParsedTemplate, constraints);
            Defaults    = GetDefaults(ParsedTemplate, defaults);
        }
        catch (Exception exception)
        {
            throw new RouteCreationException(Resources.FormatTemplateRoute_Exception(name, template), exception);
        }
    }
 public DefaultApiDescriptionProvider(
     IOptions <MvcOptions> optionsAccessor,
     IInlineConstraintResolver constraintResolver,
     IModelMetadataProvider modelMetadataProvider)
     : this(optionsAccessor, constraintResolver, modelMetadataProvider, null)
 {
 }
Esempio n. 19
0
        public TreeRouteBuilder(
            ILoggerFactory loggerFactory,
            RoutePatternBinderFactory binderFactory,
            IInlineConstraintResolver constraintResolver)
        {
            if (loggerFactory == null)
            {
                throw new ArgumentNullException(nameof(loggerFactory));
            }

            if (binderFactory == null)
            {
                throw new ArgumentNullException(nameof(binderFactory));
            }

            if (constraintResolver == null)
            {
                throw new ArgumentNullException(nameof(constraintResolver));
            }

            _binderFactory      = binderFactory;
            _constraintResolver = constraintResolver;

            _logger           = loggerFactory.CreateLogger <TreeRouter>();
            _constraintLogger = loggerFactory.CreateLogger(typeof(RouteConstraintMatcher).FullName);
        }
        public static void MapMvcAttributeRoutes(
            this RouteCollection routeCollection,
            Assembly controllerAssembly,
            IInlineConstraintResolver constraintResolver = null)
        {
            var controllerTypes = (from type in controllerAssembly.GetExportedTypes()
                                   where
                                   type != null && type.IsPublic &&
                                   type.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) &&
                                   !type.IsAbstract && typeof(IController).IsAssignableFrom(type)
                                   select type).ToList();

            routeCollection.MapMvcAttributeRoutes();
            var attributeRoutingAssembly   = typeof(RouteCollectionAttributeRoutingExtensions).Assembly;
            var attributeRoutingMapperType =
                attributeRoutingAssembly.GetType("System.Web.Mvc.Routing.AttributeRoutingMapper");

            var mapAttributeRoutesMethod = attributeRoutingMapperType.GetMethod(
                "MapAttributeRoutes",
                BindingFlags.Public | BindingFlags.Static,
                null,
                new[] { typeof(RouteCollection), typeof(IEnumerable <Type>), typeof(IInlineConstraintResolver) },
                null);

            constraintResolver = constraintResolver ?? new DefaultInlineConstraintResolver();
            mapAttributeRoutesMethod.Invoke(null, new object[] { routeCollection, controllerTypes, constraintResolver });
        }
Esempio n. 21
0
        public RouteBase(
            string template,
            string name,
            IInlineConstraintResolver constraintResolver,
            RouteValueDictionary defaults,
            IDictionary<string, object> constraints,
            RouteValueDictionary dataTokens)
        {
            if (constraintResolver == null)
            {
                throw new ArgumentNullException(nameof(constraintResolver));
            }

            template = template ?? string.Empty;
            Name = name;
            ConstraintResolver = constraintResolver;
            DataTokens = dataTokens ?? new RouteValueDictionary();

            // Data we parse from the template will be used to fill in the rest of the constraints or
            // defaults. The parser will throw for invalid routes.
            ParsedTemplate = TemplateParser.Parse(template);

            Constraints = GetConstraints(constraintResolver, ParsedTemplate, constraints);
            Defaults = GetDefaults(ParsedTemplate, defaults);
        }
        /// <summary>
        /// Maps the attribute-defined routes for the application.
        /// </summary>
        /// <param name="routes">The route collection.</param>
        /// <param name="constraintResolver">
        /// The <see cref="IInlineConstraintResolver"/> to use for resolving inline constraints in route templates.
        /// </param>
        /// <param name="directRouteProvider">
        /// The <see cref="IDirectRouteProvider"/> to use for mapping routes from controller types.
        /// </param>
        public static void MapAttributeRoutes(
            RouteCollection routes, 
            IInlineConstraintResolver constraintResolver, 
            IDirectRouteProvider directRouteProvider)
        {
            if (routes == null)
            {
                throw new ArgumentNullException("routes");
            }

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

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

            DefaultControllerFactory typesLocator =
                DependencyResolver.Current.GetService<IControllerFactory>() as DefaultControllerFactory
                ?? ControllerBuilder.Current.GetControllerFactory() as DefaultControllerFactory
                ?? new DefaultControllerFactory();

            IReadOnlyList<Type> controllerTypes = typesLocator.GetControllerTypes();

            MapAttributeRoutes(routes, controllerTypes, constraintResolver, directRouteProvider);
        }
        /// <summary>
        /// Maps the attribute-defined routes for the application.
        /// </summary>
        /// <param name="routes">The route collection.</param>
        /// <param name="constraintResolver">
        /// The <see cref="IInlineConstraintResolver"/> to use for resolving inline constraints in route templates.
        /// </param>
        /// <param name="directRouteProvider">
        /// The <see cref="IDirectRouteProvider"/> to use for mapping routes from controller types.
        /// </param>
        public static void MapAttributeRoutes(
            RouteCollection routes,
            IInlineConstraintResolver constraintResolver,
            IDirectRouteProvider directRouteProvider
            )
        {
            if (routes == null)
            {
                throw new ArgumentNullException("routes");
            }

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

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

            DefaultControllerFactory typesLocator =
                DependencyResolver.Current.GetService <IControllerFactory>()
                as DefaultControllerFactory
                ?? ControllerBuilder.Current.GetControllerFactory() as DefaultControllerFactory
                ?? new DefaultControllerFactory();

            IReadOnlyList <Type> controllerTypes = typesLocator.GetControllerTypes();

            MapAttributeRoutes(routes, controllerTypes, constraintResolver, directRouteProvider);
        }
Esempio n. 24
0
        internal static RouteEntry CreateRouteEntry(string areaPrefix, string prefix, IDirectRouteFactory factory,
            IReadOnlyCollection<ActionDescriptor> actions, IInlineConstraintResolver constraintResolver, bool targetIsAction)
        {
            Contract.Assert(factory != null);

            DirectRouteFactoryContext context = new DirectRouteFactoryContext(areaPrefix, prefix, actions,
                constraintResolver, targetIsAction);
            RouteEntry entry = factory.CreateRoute(context);

            if (entry == null)
            {
                throw new InvalidOperationException(Error.Format(MvcResources.TypeMethodMustNotReturnNull,
                    typeof(IDirectRouteFactory).Name, "CreateRoute"));
            }

            Route route = entry.Route;
            Contract.Assert(route != null);

            ActionDescriptor[] targetActions = route.GetTargetActionDescriptors();

            if (targetActions == null || targetActions.Length == 0)
            {
                throw new InvalidOperationException(MvcResources.DirectRoute_MissingActionDescriptors);
            }

            if (route.RouteHandler != null)
            {
                throw new InvalidOperationException(MvcResources.DirectRoute_RouteHandlerNotSupported);
            }

            return entry;
        }
Esempio n. 25
0
        /// <summary>
        /// Initializes a new instance of <see cref="TreeRouteBuilder"/>.
        /// </summary>
        /// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
        /// <param name="urlEncoder">The <see cref="UrlEncoder"/>.</param>
        /// <param name="objectPool">The <see cref="ObjectPool{UrlBuildingContext}"/>.</param>
        /// <param name="constraintResolver">The <see cref="IInlineConstraintResolver"/>.</param>
        public TreeRouteBuilder(
            ILoggerFactory loggerFactory,
            UrlEncoder urlEncoder,
            ObjectPool <UriBuildingContext> objectPool,
            IInlineConstraintResolver constraintResolver)
        {
            if (loggerFactory == null)
            {
                throw new ArgumentNullException(nameof(loggerFactory));
            }

            if (urlEncoder == null)
            {
                throw new ArgumentNullException(nameof(urlEncoder));
            }

            if (objectPool == null)
            {
                throw new ArgumentNullException(nameof(objectPool));
            }

            if (constraintResolver == null)
            {
                throw new ArgumentNullException(nameof(constraintResolver));
            }

            _urlEncoder         = urlEncoder;
            _objectPool         = objectPool;
            _constraintResolver = constraintResolver;

            _logger           = loggerFactory.CreateLogger <TreeRouter>();
            _constraintLogger = loggerFactory.CreateLogger(typeof(RouteConstraintMatcher).FullName);
        }
Esempio n. 26
0
        /// <summary>Creates a route builder that can build a route matching this context.</summary>
        /// <param name="template">The route template.</param>
        /// <param name="constraintResolver">
        /// The inline constraint resolver to use, if any; otherwise, <see langword="null"/>.
        /// </param>
        /// <returns>A route builder that can build a route matching this context.</returns>
        public IDirectRouteBuilder CreateBuilder(string template, IInlineConstraintResolver constraintResolver)
        {
            DirectRouteBuilder builder = new DirectRouteBuilder(_actions, _targetIsAction);

#if ASPNETWEBAPI
            string prefixedTemplate = BuildRouteTemplate(_prefix, template);
#else
            string prefixedTemplate = BuildRouteTemplate(_areaPrefix, _controllerPrefix, template ?? String.Empty);
#endif
            ValidateTemplate(prefixedTemplate);

            if (constraintResolver != null)
            {
                TRouteDictionary defaults    = new TRouteDictionary();
                TRouteDictionary constraints = new TRouteDictionary();

                string detokenizedTemplate = InlineRouteTemplateParser.ParseRouteTemplate(prefixedTemplate, defaults,
                                                                                          constraints, constraintResolver);
                TParsedRoute parsedRoute = RouteParser.Parse(detokenizedTemplate);
                decimal      precedence  = RoutePrecedence.Compute(parsedRoute, constraints);

                builder.Defaults    = defaults;
                builder.Constraints = constraints;
                builder.Template    = detokenizedTemplate;
                builder.Precedence  = precedence;
                builder.ParsedRoute = parsedRoute;
            }
            else
            {
                builder.Template = prefixedTemplate;
            }

            return(builder);
        }
Esempio n. 27
0
        public void Configure(IApplicationBuilder app, IInlineConstraintResolver resolver)
        {
            var defaultHandler = new RouteHandler(context =>
            {
                var routeValues = context.GetRouteData().Values;
                return(context.Response.WriteAsync($"Route values: {string.Join(", ", routeValues)}"));
            });

            var routes = new RouteBuilder(app, defaultHandler);

            routes.MapGet("hello", (IApplicationBuilder app2) => {
                var routes2 = new RouteBuilder(app2);
                routes2.MapGet("world", (context) => context.Response.WriteAsync("Hello World"));
                app2.UseRouter(routes2.Build());
            });

            routes.MapRoute(
                name: "Default",
                template: "{*path}"
                );

            IRouter routing = routes.Build();

            app.UseRouter(routing);
        }
        public static void MapMvcAttributeRoutes(
            this RouteCollection routeCollection,
            Assembly controllerAssembly,
            IInlineConstraintResolver constraintResolver = null)
        {
            var controllerTypes = (from type in controllerAssembly.GetExportedTypes()
                                   where
                                       type != null && type.IsPublic
                                       && type.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)
                                       && !type.IsAbstract && typeof(IController).IsAssignableFrom(type)
                                   select type).ToList();
            routeCollection.MapMvcAttributeRoutes();
            var attributeRoutingAssembly = typeof(RouteCollectionAttributeRoutingExtensions).Assembly;
            var attributeRoutingMapperType =
                attributeRoutingAssembly.GetType("System.Web.Mvc.Routing.AttributeRoutingMapper");

            var mapAttributeRoutesMethod = attributeRoutingMapperType.GetMethod(
                "MapAttributeRoutes",
                BindingFlags.Public | BindingFlags.Static,
                null,
                new[] { typeof(RouteCollection), typeof(IEnumerable<Type>), typeof(IInlineConstraintResolver) },
                null);

            constraintResolver = constraintResolver ?? new DefaultInlineConstraintResolver();
            mapAttributeRoutesMethod.Invoke(null, new object[] { routeCollection, controllerTypes, constraintResolver });
        }
        // Internal for testing
        internal static RouteEntry CreateRouteEntry(
            string areaPrefix,
            string controllerPrefix,
            IDirectRouteFactory factory,
            IReadOnlyCollection <ActionDescriptor> actions,
            IInlineConstraintResolver constraintResolver,
            bool targetIsAction)
        {
            Contract.Assert(factory != null);

            DirectRouteFactoryContext context = new DirectRouteFactoryContext(
                areaPrefix,
                controllerPrefix,
                actions,
                constraintResolver,
                targetIsAction);

            RouteEntry entry = factory.CreateRoute(context);

            if (entry == null)
            {
                throw Error.InvalidOperation(
                          MvcResources.TypeMethodMustNotReturnNull,
                          typeof(IDirectRouteFactory).Name,
                          "CreateRoute");
            }

            DirectRouteBuilder.ValidateRouteEntry(entry);

            return(entry);
        }
Esempio n. 30
0
        /// <summary>
        /// Maps the attribute-defined routes for the application.
        /// </summary>
        /// <param name="routes"></param>
        /// <param name="constraintResolver">
        /// The <see cref="IInlineConstraintResolver"/> to use for resolving inline constraints in route templates.
        /// </param>
        /// <param name="directRouteProvider">
        /// The <see cref="IDirectRouteProvider"/> to use for mapping routes.
        /// </param>
        public static void MapMvcAttributeRoutes(
            this RouteCollection routes,
            IInlineConstraintResolver constraintResolver,
            IDirectRouteProvider directRouteProvider
            )
        {
            if (routes == null)
            {
                throw new ArgumentNullException("routes");
            }

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

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

            AttributeRoutingMapper.MapAttributeRoutes(
                routes,
                constraintResolver,
                directRouteProvider
                );
        }
Esempio n. 31
0
        private static IReadOnlyList <RouteEntry> CreateRouteEntries(
            string areaPrefix,
            string controllerPrefix,
            IReadOnlyCollection <IDirectRouteFactory> factories,
            IReadOnlyCollection <ActionDescriptor> actions,
            IInlineConstraintResolver constraintResolver,
            bool targetIsAction
            )
        {
            List <RouteEntry> entries = new List <RouteEntry>();

            foreach (IDirectRouteFactory factory in factories)
            {
                RouteEntry entry = CreateRouteEntry(
                    areaPrefix,
                    controllerPrefix,
                    factory,
                    actions,
                    constraintResolver,
                    targetIsAction
                    );
                entries.Add(entry);
            }

            return(entries);
        }
Esempio n. 32
0
        /// <summary>
        /// Maps the attribute-defined routes for the application.
        /// </summary>
        /// <param name="routes"></param>
        /// <param name="controllerTypes">The controller types to scan.</param>
        /// <param name="constraintResolver">
        /// The <see cref="IInlineConstraintResolver"/> to use for resolving inline constraints in route templates.
        /// </param>
        public static void MapAttributeRoutes(RouteCollection routes, IEnumerable<Type> controllerTypes,
            IInlineConstraintResolver constraintResolver)
        {
            SubRouteCollection subRoutes = new SubRouteCollection();
            AddRouteEntries(subRoutes, controllerTypes, constraintResolver);
            IReadOnlyCollection<RouteEntry> entries = subRoutes.Entries;

            if (entries.Count > 0)
            {
                RouteCollectionRoute aggregrateRoute = new RouteCollectionRoute(subRoutes);
                routes.Add(aggregrateRoute);

                // This sort is here to enforce a static ordering for link generation using these routes. 
                // We don't apply dynamic criteria like ActionSelectors on link generation, but we can use the static
                // ones.
                //
                // Routes to actions are placed first because they are considered more specific. A route to an action
                // will only match for link generation if the action name was supplied, so this is essential for
                // correctness. Without this a controller-level route could be 'greedy' and generate a link when
                // the action-level route was intended.
                RouteEntry[] sorted = entries
                    .OrderBy(r => r.Route.GetOrder())
                    .ThenBy(r => r.Route.GetTargetIsAction() ? 0 : 1)
                    .ThenBy(r => r.Route.GetPrecedence())
                    .ToArray();

                AddGenerationHooksForSubRoutes(routes, sorted);
            }
        }
Esempio n. 33
0
        private static IHttpRoute BuildWithResolver(
            string template,
            IInlineConstraintResolver constraintResolver
            )
        {
            HttpActionDescriptor[] actions = new HttpActionDescriptor[]
            {
                new ReflectedHttpActionDescriptor()
            };
            DirectRouteFactoryContext context = new DirectRouteFactoryContext(
                null,
                actions,
                constraintResolver,
                targetIsAction: true
                );

            // Act
            IDirectRouteBuilder builder = context.CreateBuilder(template);
            IHttpRoute          route   = builder.Build().Route;

            // Assertions for default, unspecified behavior:
            Assert.NotNull(route);
            Assert.Equal(actions, route.DataTokens["actions"]);

            return(route);
        }
        public static void MapAttributeRoutesInAssembly(this RouteCollection routes, Assembly assembly, IInlineConstraintResolver constraintResolver, IDirectRouteProvider routeProvider)
        {
            var controllers = (assembly.GetExportedTypes()
                .Where(IsControllerType)).ToList();

            MapAttributeRoutesInControllers(routes, controllers, constraintResolver, routeProvider);
        }
Esempio n. 35
0
        protected static IDictionary <string, IRouteConstraint> GetConstraints(
            IInlineConstraintResolver inlineConstraintResolver,
            RouteTemplate parsedTemplate,
            IDictionary <string, object> constraints)
        {
            var constraintBuilder = new RouteConstraintBuilder(inlineConstraintResolver, parsedTemplate.TemplateText);

            if (constraints != null)
            {
                foreach (var kvp in constraints)
                {
                    constraintBuilder.AddConstraint(kvp.Key, kvp.Value);
                }
            }

            foreach (var parameter in parsedTemplate.Parameters)
            {
                if (parameter.IsOptional)
                {
                    constraintBuilder.SetOptional(parameter.Name);
                }

                foreach (var inlineConstraint in parameter.InlineConstraints)
                {
                    constraintBuilder.AddResolvedConstraint(parameter.Name, inlineConstraint.Constraint);
                }
            }

            return(constraintBuilder.Build());
        }
Esempio n. 36
0
 IReadOnlyList<RouteEntry> IDirectRouteProvider.GetDirectRoutes(HttpControllerDescriptor controllerDescriptor, IReadOnlyList<HttpActionDescriptor> actionDescriptors,
     IInlineConstraintResolver constraintResolver)
 {
     var routes = _provider.GetDirectRoutes(controllerDescriptor, actionDescriptors, constraintResolver);
     var list = new List<RouteEntry>();
     foreach (var route in routes)
     {
         var newRoute = new RouteEntry(route.Name ?? Guid.NewGuid().ToString(), route.Route);
         list.Add(newRoute);
         var descs = route.Route.GetTargetActionDescriptors();
         if (descs.Length == 0)
         {
             continue;
         }
         foreach (var desc in descs)
         {
             var reflDesc = desc as ReflectedHttpActionDescriptor;
             if (reflDesc == null)
             {
                 continue;
             }
             var method = reflDesc.MethodInfo;
             RouteEntry prevEntry;
             if (_map.TryGetValue(method, out prevEntry))
             {
                 throw new MultipleRoutesForSameMethodException(reflDesc, prevEntry, newRoute);
             }
             _map.Add(method, newRoute);
         }
     }
     return list;
 }
Esempio n. 37
0
        internal virtual DirectRouteBuilder CreateBuilder(string template,
                                                          IInlineConstraintResolver constraintResolver)
        {
            DirectRouteBuilder builder = new DirectRouteBuilder(_actions);

            string prefixedTemplate = BuildRouteTemplate(_prefix, template);

            Contract.Assert(prefixedTemplate != null);

            if (prefixedTemplate.StartsWith("/", StringComparison.Ordinal))
            {
                throw Error.InvalidOperation(SRResources.AttributeRoutes_InvalidTemplate, template, _actionName);
            }

            if (constraintResolver != null)
            {
                builder.Defaults    = new HttpRouteValueDictionary();
                builder.Constraints = new HttpRouteValueDictionary();
                builder.Template    = InlineRouteTemplateParser.ParseRouteTemplate(prefixedTemplate, builder.Defaults,
                                                                                   builder.Constraints, constraintResolver);
                builder.ParsedRoute = HttpRouteParser.Parse(builder.Template);
                builder.Precedence  = RoutePrecedence.Compute(builder.ParsedRoute, builder.Constraints);
            }
            else
            {
                builder.Template = prefixedTemplate;
            }

            return(builder);
        }
Esempio n. 38
0
        public AttributeRoute(
            IRouter target,
            IActionDescriptorsCollectionProvider actionDescriptorsCollectionProvider,
            IInlineConstraintResolver constraintResolver,
            ILoggerFactory loggerFactory)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            if (actionDescriptorsCollectionProvider == null)
            {
                throw new ArgumentNullException(nameof(actionDescriptorsCollectionProvider));
            }

            if (constraintResolver == null)
            {
                throw new ArgumentNullException(nameof(constraintResolver));
            }

            if (loggerFactory == null)
            {
                throw new ArgumentNullException(nameof(loggerFactory));
            }

            _target = target;
            _actionDescriptorsCollectionProvider = actionDescriptorsCollectionProvider;
            _constraintResolver = constraintResolver;

            _routeLogger      = loggerFactory.CreateLogger <InnerAttributeRoute>();
            _constraintLogger = loggerFactory.CreateLogger(typeof(RouteConstraintMatcher).FullName);
        }
Esempio n. 39
0
            public override IReadOnlyList <RouteEntry> GetDirectRoutes(HttpControllerDescriptor controllerDescriptor, IReadOnlyList <HttpActionDescriptor> actionDescriptors,
                                                                       IInlineConstraintResolver constraintResolver)
            {
                var result = base.GetDirectRoutes(controllerDescriptor, actionDescriptors, constraintResolver);

                return(result);
            }
Esempio n. 40
0
        private static void RegisterAutomaticRoutes(
            RouteCollection routes,
            IInlineConstraintResolver constraintResolver)
        {
            routes.MapMvcAttributeRoutes(constraintResolver);

            AreaRegistration.RegisterAllAreas();
        }
        public override IReadOnlyList<RouteEntry> GetDirectRoutes(HttpControllerDescriptor controllerDescriptor, IReadOnlyList<HttpActionDescriptor> actionDescriptors, IInlineConstraintResolver constraintResolver)
        {
            var routes = base.GetDirectRoutes(controllerDescriptor, actionDescriptors, constraintResolver);

            DirectRoutes.AddRange(routes);

            return routes;
        }
Esempio n. 42
0
 public TemplateRoute([NotNull] IRouter target,
                      string routeTemplate,
                      IDictionary<string, object> defaults,
                      IDictionary<string, object> constraints,
                      IDictionary<string, object> dataTokens,
                      IInlineConstraintResolver inlineConstraintResolver)
     : this(target, null, routeTemplate, defaults, constraints, dataTokens, inlineConstraintResolver)
 {
 }
        public SubdomainTemplateRoute(IRouter target, string routeName, string subdomainTemplate, string routeTemplate, IDictionary<string, object> defaults, IDictionary<string, object> constraints, IDictionary<string, object> dataTokens, IInlineConstraintResolver inlineConstraintResolver) {
            _innerRoute = new TemplateRoute(target, routeName, routeTemplate, defaults, constraints, dataTokens, inlineConstraintResolver);
            _subdomainTemplate = subdomainTemplate;
            _target = target;

            _matcher = new TemplateMatcher(TemplateParser.Parse(subdomainTemplate), Defaults);

            Name = routeName;
        }
        /// <summary>
        /// Maps the attribute-defined routes for the application.
        /// </summary>
        /// <param name="routes"></param>
        /// <param name="controllerTypes">The controller types to scan.</param>
        /// <param name="constraintResolver">The <see cref="IInlineConstraintResolver"/> to use for resolving inline constraints in route templates.</param>
        public static void MapMvcAttributeRoutes(this RouteCollection routes, IEnumerable<Type> controllerTypes, IInlineConstraintResolver constraintResolver)
        {
            List<RouteEntry> routeEntries = new AttributeRoutingMapper(new RouteBuilder(constraintResolver)).MapMvcAttributeRoutes(controllerTypes);

            foreach (var routeEntry in routeEntries)
            {
                routes.Add(routeEntry.Name, routeEntry.Route);
            }
        }
Esempio n. 45
0
        /// <summary>
        /// Initializes a new instance of the <see cref="HttpRouteBuilder" /> class.
        /// </summary>
        /// <param name="constraintResolver">The <see cref="IInlineConstraintResolver"/> to use for resolving inline constraints.</param>
        public HttpRouteBuilder(IInlineConstraintResolver constraintResolver)
        {
            if (constraintResolver == null)
            {
                throw Error.ArgumentNull("constraintResolver");
            }

            ConstraintResolver = constraintResolver;
        }
Esempio n. 46
0
 public Route(
     IRouter target,
     string routeTemplate,
     RouteValueDictionary defaults,
     IDictionary<string, object> constraints,
     RouteValueDictionary dataTokens,
     IInlineConstraintResolver inlineConstraintResolver)
     : this(target, null, routeTemplate, defaults, constraints, dataTokens, inlineConstraintResolver)
 {
 }
Esempio n. 47
0
        public MetaWeblogRoute(IRouter target,
                             string routeName,
                             string routeTemplate,
							 RouteValueDictionary defaults,
                             IDictionary<string, object> constraints,
							 RouteValueDictionary dataTokens,
                             IInlineConstraintResolver inlineConstraintResolver)
            : base(target, routeName, routeTemplate, defaults, 
                  constraints, dataTokens, inlineConstraintResolver)
        { }
Esempio n. 48
0
 protected override IReadOnlyList<RouteEntry> GetActionDirectRoutes(HttpActionDescriptor actionDescriptor, IReadOnlyList<IDirectRouteFactory> factories,
     IInlineConstraintResolver constraintResolver)
 {
     var result = base.GetActionDirectRoutes(actionDescriptor, factories, constraintResolver);
     var descriptors = result.SelectMany(r => r.Route.DataTokens).Where(dt => dt.Key.Equals("actions", StringComparison.InvariantCultureIgnoreCase)).Select(dt => dt.Value).Cast<HttpActionDescriptor[]>().SelectMany(ad => ad).Cast<ReflectedHttpActionDescriptor>();
     var controllerTypes = descriptors.Select(d => d.ControllerDescriptor.ControllerType);
     if (!controllers.IsRegistered(controllerTypes.Single()))
         return new ArraySegment<RouteEntry>();
     return result;
 }
Esempio n. 49
0
        /// <summary>
        /// Creates a new <see cref="RouteConstraintBuilder"/> instance.
        /// </summary>
        /// <param name="inlineConstraintResolver">The <see cref="IInlineConstraintResolver"/>.</param>
        /// <param name="displayName">The display name (for use in error messages).</param>
        public RouteConstraintBuilder(
            [NotNull] IInlineConstraintResolver inlineConstraintResolver,
            [NotNull] string displayName)
        {
            _inlineConstraintResolver = inlineConstraintResolver;
            _displayName = displayName;

            _constraints = new Dictionary<string, List<IRouteConstraint>>(StringComparer.OrdinalIgnoreCase);
            _optionalParameters = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
        }
        /// <summary>
        /// Maps the attribute-defined routes for the application.
        /// </summary>
        /// <param name="routes"></param>
        /// <param name="constraintResolver">The <see cref="IInlineConstraintResolver"/> to use for resolving inline constraints in route templates.</param>
        public static void MapMvcAttributeRoutes(this RouteCollection routes, IInlineConstraintResolver constraintResolver)
        {
            DefaultControllerFactory typesLocator =
                DependencyResolver.Current.GetService<IControllerFactory>() as DefaultControllerFactory
                ?? ControllerBuilder.Current.GetControllerFactory() as DefaultControllerFactory
                ?? new DefaultControllerFactory();

            IReadOnlyList<Type> controllerTypes = typesLocator.GetControllerTypes();

            MapMvcAttributeRoutes(routes, controllerTypes, constraintResolver);
        }
Esempio n. 51
0
		public AttributeRouteFetcher(
			IInlineConstraintResolver constraintResolver,
			IActionDescriptorsCollectionProvider actionDescriptorsCollectionProvider,
			IRouteTemplateParser parser, 
			IConstraintsProcessor constraintsProcessor
		)
		{
			_constraintResolver = constraintResolver;
			_actionDescriptorsCollectionProvider = actionDescriptorsCollectionProvider;
			_parser = parser;
			_constraintsProcessor = constraintsProcessor;
		}
Esempio n. 52
0
 public TemplateRoute(
     [NotNull] IRouter target,
     string routeTemplate,
     IInlineConstraintResolver inlineConstraintResolver)
                 : this(target,
                        routeTemplate,
                        defaults: null,
                        constraints: null,
                        dataTokens: null,
                        inlineConstraintResolver: inlineConstraintResolver)
 {
 }
 public ReflectedActionDescriptorProvider(IControllerAssemblyProvider controllerAssemblyProvider,
                                          IActionDiscoveryConventions conventions,
                                          IEnumerable<IFilter> globalFilters,
                                          IOptionsAccessor<MvcOptions> optionsAccessor,
                                          IInlineConstraintResolver constraintResolver)
 {
     _controllerAssemblyProvider = controllerAssemblyProvider;
     _conventions = conventions;
     _globalFilters = globalFilters ?? Enumerable.Empty<IFilter>();
     _modelConventions = optionsAccessor.Options.ApplicationModelConventions;
     _constraintResolver = constraintResolver;
 }
 public static UriMakerContext MapHttpAttributeRoutesAndUseUriMaker(
     this HttpConfiguration configuration,           
     IInlineConstraintResolver constraintResolver,
     IDirectRouteProvider directRouteProvider = null,
     Func<HttpRequestMessage, ICollection<RouteEntry>, RouteEntry> routeSelector = null)
 {
     directRouteProvider = directRouteProvider ?? new DefaultDirectRouteProvider();
     var decorator = new DecoratorRouteProvider(directRouteProvider, routeSelector);
     configuration.MapHttpAttributeRoutes(constraintResolver, decorator);
     var uriMakerContext = new UriMakerContext(decorator.RouteMap);
     configuration.Properties.AddOrUpdate(ContextKey, _ => uriMakerContext, (_, __) => uriMakerContext);
     return uriMakerContext;
 }
Esempio n. 55
0
        public AttributeRoute(
            [NotNull] IRouter target,
            [NotNull] IActionDescriptorsCollectionProvider actionDescriptorsCollectionProvider,
            [NotNull] IInlineConstraintResolver constraintResolver,
            [NotNull] ILoggerFactory loggerFactory)
        {
            _target = target;
            _actionDescriptorsCollectionProvider = actionDescriptorsCollectionProvider;
            _constraintResolver = constraintResolver;

            _routeLogger = loggerFactory.CreateLogger<InnerAttributeRoute>();
            _constraintLogger = loggerFactory.CreateLogger(typeof(RouteConstraintMatcher).FullName);
        }
        public static void MapAttributeRoutes(
            HttpConfiguration configuration,
            IInlineConstraintResolver constraintResolver,
            IDirectRouteProvider directRouteProvider)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException("configuration");
            }

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

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

            RouteCollectionRoute aggregateRoute = new RouteCollectionRoute();
            configuration.Routes.Add(AttributeRouteName, aggregateRoute);

            Action<HttpConfiguration> previousInitializer = configuration.Initializer;
            configuration.Initializer = config =>
                {
                    // Chain to the previous initializer hook. Do this before we access the config since
                    // initialization may make last minute changes to the configuration.
                    previousInitializer(config);

                    SubRouteCollection subRoutes = null;

                    // Add a single placeholder route that handles all of attribute routing.
                    // Add an initialize hook that initializes these routes after the config has been initialized.
                    Func<SubRouteCollection> initializer = () =>
                    {
                        subRoutes = new SubRouteCollection();
                        AddRouteEntries(subRoutes, configuration, constraintResolver, directRouteProvider);
                        return subRoutes;
                    };

                    // This won't change config. It wants to pick up the finalized config.
                    aggregateRoute.EnsureInitialized(initializer);

                    if (subRoutes != null)
                    {
                        AddGenerationHooksForSubRoutes(config.Routes, subRoutes.Entries);
                    }
                };
        }
        private static IHttpRoute BuildRoute(string routeTemplate, IInlineConstraintResolver constraintResolver = null)
        {
            ReflectedHttpActionDescriptor[] actions = new ReflectedHttpActionDescriptor[0];

            // Act
            HttpRouteBuilder routeBuilder = new HttpRouteBuilder(constraintResolver ?? new DefaultInlineConstraintResolver());
            IHttpRoute route = routeBuilder.BuildHttpRoute(routeTemplate, actions: actions);

            // Assertions for default, unspecified behavior:
            Assert.NotNull(route);
            Assert.Same(actions, route.DataTokens["actions"]);
            
            return route;
        }
        /// <summary>
        /// Maps the attribute-defined routes for the application.
        /// </summary>
        /// <param name="routes">The route collection.</param>
        /// <param name="constraintResolver">
        /// The <see cref="IInlineConstraintResolver"/> to use for resolving inline constraints in route templates.
        /// </param>
        public static void MapAttributeRoutes(RouteCollection routes, IInlineConstraintResolver constraintResolver)
        {
            if (routes == null)
            {
                throw new ArgumentNullException("routes");
            }

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

            MapAttributeRoutes(routes, constraintResolver, new DefaultDirectRouteProvider());
        }
        /// <summary>
        /// Maps the attribute-defined routes for the application.
        /// </summary>
        /// <param name="routes"></param>
        /// <param name="constraintResolver">
        /// The <see cref="IInlineConstraintResolver"/> to use for resolving inline constraints in route templates.
        /// </param>
        public static void MapMvcAttributeRoutes(this RouteCollection routes,
            IInlineConstraintResolver constraintResolver)
        {
            if (routes == null)
            {
                throw new ArgumentNullException("routes");
            }

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

            AttributeRoutingMapper.MapAttributeRoutes(routes, constraintResolver);
        }