// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using System.Web.Http.Controllers; using System.Web.Http.Filters; using System.Web.Http.Hosting; using System.Web.Http.ModelBinding; using System.Web.Http.ModelBinding.Binders; using System.Web.Http.Routing; namespace System.Web.Http { [EditorBrowsable(EditorBrowsableState.Never)] public static class HttpConfigurationExtensions { /// /// Register that the given parameter type on an Action is to be bound using the model binder. /// /// configuration to be updated. /// parameter type that binder is applied to /// a model binder public static void BindParameter(this HttpConfiguration configuration, Type type, IModelBinder binder) { if (configuration == null) { throw Error.ArgumentNull("configuration"); } if (type == null) { throw Error.ArgumentNull("type"); } if (binder == null) { throw Error.ArgumentNull("binder"); } // Add a provider so that we can use this type recursively // Be sure to insert at position 0 to preempt any eager binders (eg, MutableObjectBinder) that // may eagerly claim all types. configuration.Services.Insert(typeof(ModelBinderProvider), 0, new SimpleModelBinderProvider(type, binder)); // Add the binder to the list of rules. // This ensures that the parameter binding will actually use model binding instead of Formatters. // Without this, the parameter binding system may see the parameter type is complex and choose // to use formatters instead, in which case it would ignore the registered model binders. configuration.ParameterBindingRules.Insert(0, type, param => param.BindWithModelBinding(binder)); } /// /// Maps the attribute-defined routes for the application. /// /// The server configuration. // Corresponds to the MVC implementation of attribute routing in // System.Web.Mvc.RouteCollectionAttributeRoutingExtensions. public static void MapHttpAttributeRoutes(this HttpConfiguration configuration) { if (configuration == null) { throw new ArgumentNullException("configuration"); } AttributeRoutingMapper.MapAttributeRoutes(configuration, new DefaultInlineConstraintResolver(), new DefaultDirectRouteProvider()); } /// /// Maps the attribute-defined routes for the application. /// /// The server configuration. /// /// The to use for resolving inline constraints. /// // Corresponds to the MVC implementation of attribute routing in // System.Web.Mvc.RouteCollectionAttributeRoutingExtensions. public static void MapHttpAttributeRoutes(this HttpConfiguration configuration, IInlineConstraintResolver constraintResolver) { if (configuration == null) { throw new ArgumentNullException("configuration"); } if (constraintResolver == null) { throw new ArgumentNullException("constraintResolver"); } AttributeRoutingMapper.MapAttributeRoutes(configuration, constraintResolver, new DefaultDirectRouteProvider()); } /// /// Maps the attribute-defined routes for the application. /// /// The server configuration. /// /// The to use for discovering and building routes. /// // Corresponds to the MVC implementation of attribute routing in // System.Web.Mvc.RouteCollectionAttributeRoutingExtensions. public static void MapHttpAttributeRoutes( this HttpConfiguration configuration, IDirectRouteProvider directRouteProvider) { if (configuration == null) { throw new ArgumentNullException("configuration"); } if (directRouteProvider == null) { throw new ArgumentNullException("directRouteProvider"); } AttributeRoutingMapper.MapAttributeRoutes(configuration, new DefaultInlineConstraintResolver(), directRouteProvider); } /// /// Maps the attribute-defined routes for the application. /// /// The server configuration. /// /// The to use for resolving inline constraints. /// /// /// The to use for discovering and building routes. /// // Corresponds to the MVC implementation of attribute routing in // System.Web.Mvc.RouteCollectionAttributeRoutingExtensions. public static void MapHttpAttributeRoutes( this 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"); } AttributeRoutingMapper.MapAttributeRoutes(configuration, constraintResolver, directRouteProvider); } // Test Hook for inspecting the route table generated by MapHttpAttributeRoutes. // MapHttpAttributeRoutes doesn't return the route collection because it's an implementation detail // that attr routes even generate a meaningful route collection. // Public APIs can get similar functionality by querying the IHttpRoute for IReadOnlyCollection. internal static IReadOnlyCollection GetAttributeRoutes(this HttpConfiguration configuration) { configuration.EnsureInitialized(); HttpRouteCollection routes = configuration.Routes; foreach (IHttpRoute route in routes) { var attrRoute = route as IReadOnlyCollection; if (attrRoute != null) { return attrRoute; } } return null; } /// Enables suppression of the host's principal. /// The server configuration. /// /// When the host's principal is suppressed, the current principal is set to anonymous upon entering the /// 's first message handler. As a result, any authentication performed by the host is /// ignored. The remaining pipeline within the , including /// s, is then the exclusive authority for authentication. /// [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Message handler should be disposed with parent configuration.")] public static void SuppressHostPrincipal(this HttpConfiguration configuration) { if (configuration == null) { throw new ArgumentNullException("configuration"); } Contract.Assert(configuration.MessageHandlers != null); configuration.MessageHandlers.Insert(0, new SuppressHostPrincipalMessageHandler()); } } }