Adding IRouteConstraintProvider and supporting it on actions
This change adds an interface for the functionality provide by RouteConstraintAttribute, and adds support for configuration constraints on actions/action-model.
This commit is contained in:
parent
5dfd27e51f
commit
ae9fc793ec
|
|
@ -20,6 +20,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
Filters = new List<IFilter>();
|
Filters = new List<IFilter>();
|
||||||
HttpMethods = new List<string>();
|
HttpMethods = new List<string>();
|
||||||
Parameters = new List<ParameterModel>();
|
Parameters = new List<ParameterModel>();
|
||||||
|
RouteConstraints = new List<IRouteConstraintProvider>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionModel([NotNull] ActionModel other)
|
public ActionModel([NotNull] ActionModel other)
|
||||||
|
|
@ -40,6 +41,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
// Make a deep copy of other 'model' types.
|
// Make a deep copy of other 'model' types.
|
||||||
ApiExplorer = new ApiExplorerModel(other.ApiExplorer);
|
ApiExplorer = new ApiExplorerModel(other.ApiExplorer);
|
||||||
Parameters = new List<ParameterModel>(other.Parameters.Select(p => new ParameterModel(p)));
|
Parameters = new List<ParameterModel>(other.Parameters.Select(p => new ParameterModel(p)));
|
||||||
|
RouteConstraints = new List<IRouteConstraintProvider>(other.RouteConstraints);
|
||||||
|
|
||||||
if (other.AttributeRouteModel != null)
|
if (other.AttributeRouteModel != null)
|
||||||
{
|
{
|
||||||
|
|
@ -62,6 +64,8 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public ApiExplorerModel ApiExplorer { get; set; }
|
public ApiExplorerModel ApiExplorer { get; set; }
|
||||||
|
|
||||||
|
public AttributeRouteModel AttributeRouteModel { get; set; }
|
||||||
|
|
||||||
public IReadOnlyList<object> Attributes { get; }
|
public IReadOnlyList<object> Attributes { get; }
|
||||||
|
|
||||||
public ControllerModel Controller { get; set; }
|
public ControllerModel Controller { get; set; }
|
||||||
|
|
@ -74,6 +78,6 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
|
|
||||||
public List<ParameterModel> Parameters { get; private set; }
|
public List<ParameterModel> Parameters { get; private set; }
|
||||||
|
|
||||||
public AttributeRouteModel AttributeRouteModel { get; set; }
|
public List<IRouteConstraintProvider> RouteConstraints { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.AspNet.Mvc.Core;
|
using Microsoft.AspNet.Mvc.Core;
|
||||||
using Microsoft.AspNet.Mvc.Routing;
|
using Microsoft.AspNet.Mvc.Routing;
|
||||||
|
|
@ -336,7 +337,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
var message = Resources.FormatAttributeRoute_TokenReplacement_ReplacementValueNotFound(
|
var message = Resources.FormatAttributeRoute_TokenReplacement_ReplacementValueNotFound(
|
||||||
template,
|
template,
|
||||||
token,
|
token,
|
||||||
string.Join(", ", values.Keys));
|
string.Join(", ", values.Keys.OrderBy(k => k, StringComparer.OrdinalIgnoreCase)));
|
||||||
throw new InvalidOperationException(message);
|
throw new InvalidOperationException(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
AttributeRoutes = new List<AttributeRouteModel>();
|
AttributeRoutes = new List<AttributeRouteModel>();
|
||||||
ActionConstraints = new List<IActionConstraintMetadata>();
|
ActionConstraints = new List<IActionConstraintMetadata>();
|
||||||
Filters = new List<IFilter>();
|
Filters = new List<IFilter>();
|
||||||
RouteConstraints = new List<RouteConstraintAttribute>();
|
RouteConstraints = new List<IRouteConstraintProvider>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ControllerModel([NotNull] ControllerModel other)
|
public ControllerModel([NotNull] ControllerModel other)
|
||||||
|
|
@ -35,7 +35,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
ActionConstraints = new List<IActionConstraintMetadata>(other.ActionConstraints);
|
ActionConstraints = new List<IActionConstraintMetadata>(other.ActionConstraints);
|
||||||
Attributes = new List<object>(other.Attributes);
|
Attributes = new List<object>(other.Attributes);
|
||||||
Filters = new List<IFilter>(other.Filters);
|
Filters = new List<IFilter>(other.Filters);
|
||||||
RouteConstraints = new List<RouteConstraintAttribute>(other.RouteConstraints);
|
RouteConstraints = new List<IRouteConstraintProvider>(other.RouteConstraints);
|
||||||
|
|
||||||
// Make a deep copy of other 'model' types.
|
// Make a deep copy of other 'model' types.
|
||||||
Actions = new List<ActionModel>(other.Actions.Select(a => new ActionModel(a)));
|
Actions = new List<ActionModel>(other.Actions.Select(a => new ActionModel(a)));
|
||||||
|
|
@ -65,6 +65,6 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
|
|
||||||
public List<IFilter> Filters { get; private set; }
|
public List<IFilter> Filters { get; private set; }
|
||||||
|
|
||||||
public List<RouteConstraintAttribute> RouteConstraints { get; private set; }
|
public List<IRouteConstraintProvider> RouteConstraints { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -289,6 +289,8 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
.SelectMany(a => a.HttpMethods)
|
.SelectMany(a => a.HttpMethods)
|
||||||
.Distinct());
|
.Distinct());
|
||||||
|
|
||||||
|
actionModel.RouteConstraints.AddRange(attributes.OfType<IRouteConstraintProvider>());
|
||||||
|
|
||||||
var routeTemplateProvider =
|
var routeTemplateProvider =
|
||||||
attributes
|
attributes
|
||||||
.OfType<IRouteTemplateProvider>()
|
.OfType<IRouteTemplateProvider>()
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
|
|
||||||
controllerModel.ActionConstraints.AddRange(attributes.OfType<IActionConstraintMetadata>());
|
controllerModel.ActionConstraints.AddRange(attributes.OfType<IActionConstraintMetadata>());
|
||||||
controllerModel.Filters.AddRange(attributes.OfType<IFilter>());
|
controllerModel.Filters.AddRange(attributes.OfType<IFilter>());
|
||||||
controllerModel.RouteConstraints.AddRange(attributes.OfType<RouteConstraintAttribute>());
|
controllerModel.RouteConstraints.AddRange(attributes.OfType<IRouteConstraintProvider>());
|
||||||
|
|
||||||
controllerModel.AttributeRoutes.AddRange(
|
controllerModel.AttributeRoutes.AddRange(
|
||||||
attributes.OfType<IRouteTemplateProvider>().Select(rtp => new AttributeRouteModel(rtp)));
|
attributes.OfType<IRouteTemplateProvider>().Select(rtp => new AttributeRouteModel(rtp)));
|
||||||
|
|
@ -142,4 +142,4 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
return controllerModel;
|
return controllerModel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,11 +56,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
actionDescriptor.ControllerTypeInfo = controller.ControllerType;
|
actionDescriptor.ControllerTypeInfo = controller.ControllerType;
|
||||||
|
|
||||||
AddApiExplorerInfo(actionDescriptor, action, controller);
|
AddApiExplorerInfo(actionDescriptor, action, controller);
|
||||||
AddRouteConstraints(actionDescriptor, controller, action);
|
AddRouteConstraints(removalConstraints, actionDescriptor, controller, action);
|
||||||
AddControllerRouteConstraints(
|
|
||||||
actionDescriptor,
|
|
||||||
controller.RouteConstraints,
|
|
||||||
removalConstraints);
|
|
||||||
|
|
||||||
if (IsAttributeRoutedAction(actionDescriptor))
|
if (IsAttributeRoutedAction(actionDescriptor))
|
||||||
{
|
{
|
||||||
|
|
@ -371,39 +367,17 @@ namespace Microsoft.AspNet.Mvc
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddRouteConstraints(
|
public static void AddRouteConstraints(
|
||||||
|
ISet<string> removalConstraints,
|
||||||
ControllerActionDescriptor actionDescriptor,
|
ControllerActionDescriptor actionDescriptor,
|
||||||
ControllerModel controller,
|
ControllerModel controller,
|
||||||
ActionModel action)
|
ActionModel action)
|
||||||
{
|
{
|
||||||
actionDescriptor.RouteConstraints.Add(new RouteDataActionConstraint(
|
// Apply all the constraints defined on the action, then controller (for example, [Area])
|
||||||
"controller",
|
// to the actions. Also keep track of all the constraints that require preventing actions
|
||||||
controller.ControllerName));
|
|
||||||
|
|
||||||
if (action.IsActionNameMatchRequired)
|
|
||||||
{
|
|
||||||
actionDescriptor.RouteConstraints.Add(new RouteDataActionConstraint(
|
|
||||||
"action",
|
|
||||||
action.ActionName));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
actionDescriptor.RouteConstraints.Add(new RouteDataActionConstraint(
|
|
||||||
"action",
|
|
||||||
string.Empty));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void AddControllerRouteConstraints(
|
|
||||||
ControllerActionDescriptor actionDescriptor,
|
|
||||||
IList<RouteConstraintAttribute> routeconstraints,
|
|
||||||
ISet<string> removalConstraints)
|
|
||||||
{
|
|
||||||
// Apply all the constraints defined on the controller (for example, [Area]) to the actions
|
|
||||||
// in that controller. 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
|
// 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
|
// controller should not match when a value has been given for area when matching a url or
|
||||||
// generating a link.
|
// generating a link.
|
||||||
foreach (var constraintAttribute in routeconstraints)
|
foreach (var constraintAttribute in action.RouteConstraints)
|
||||||
{
|
{
|
||||||
if (constraintAttribute.BlockNonAttributedActions)
|
if (constraintAttribute.BlockNonAttributedActions)
|
||||||
{
|
{
|
||||||
|
|
@ -427,6 +401,55 @@ namespace Microsoft.AspNet.Mvc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var constraintAttribute in controller.RouteConstraints)
|
||||||
|
{
|
||||||
|
if (constraintAttribute.BlockNonAttributedActions)
|
||||||
|
{
|
||||||
|
removalConstraints.Add(constraintAttribute.RouteKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip duplicates - this also means that a value on the action will take precedence
|
||||||
|
if (!HasConstraint(actionDescriptor.RouteConstraints, constraintAttribute.RouteKey))
|
||||||
|
{
|
||||||
|
if (constraintAttribute.RouteKeyHandling == RouteKeyHandling.CatchAll)
|
||||||
|
{
|
||||||
|
actionDescriptor.RouteConstraints.Add(
|
||||||
|
RouteDataActionConstraint.CreateCatchAll(
|
||||||
|
constraintAttribute.RouteKey));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
actionDescriptor.RouteConstraints.Add(new RouteDataActionConstraint(
|
||||||
|
constraintAttribute.RouteKey,
|
||||||
|
constraintAttribute.RouteValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lastly add the 'default' values
|
||||||
|
if (!HasConstraint(actionDescriptor.RouteConstraints, "action"))
|
||||||
|
{
|
||||||
|
if (action.IsActionNameMatchRequired)
|
||||||
|
{
|
||||||
|
actionDescriptor.RouteConstraints.Add(new RouteDataActionConstraint(
|
||||||
|
"action",
|
||||||
|
action.ActionName));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
actionDescriptor.RouteConstraints.Add(new RouteDataActionConstraint(
|
||||||
|
"action",
|
||||||
|
string.Empty));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!HasConstraint(actionDescriptor.RouteConstraints, "controller"))
|
||||||
|
{
|
||||||
|
actionDescriptor.RouteConstraints.Add(new RouteDataActionConstraint(
|
||||||
|
"controller",
|
||||||
|
controller.ControllerName));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool HasConstraint(List<RouteDataActionConstraint> constraints, string routeKey)
|
private static bool HasConstraint(List<RouteDataActionConstraint> constraints, string routeKey)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An interface for metadata which provides <see cref="RouteDataActionConstraint"/> values
|
||||||
|
/// for a controller or action.
|
||||||
|
/// </summary>
|
||||||
|
public interface IRouteConstraintProvider
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The route value key.
|
||||||
|
/// </summary>
|
||||||
|
string RouteKey { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="RouteKeyHandling"/>.
|
||||||
|
/// </summary>
|
||||||
|
RouteKeyHandling RouteKeyHandling { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The expected route value. Will be null unless <see cref="RouteKeyHandling"/> is
|
||||||
|
/// set to <see cref="RouteKeyHandling.RequireKey"/>.
|
||||||
|
/// </summary>
|
||||||
|
string RouteValue { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set to true to negate this constraint on all actions that do not define a behavior for this route key.
|
||||||
|
/// </summary>
|
||||||
|
bool BlockNonAttributedActions { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -24,6 +24,8 @@ namespace Microsoft.AspNet.Mvc.Logging
|
||||||
ActionMethod = inner.ActionMethod;
|
ActionMethod = inner.ActionMethod;
|
||||||
ApiExplorer = new ApiExplorerModelValues(inner.ApiExplorer);
|
ApiExplorer = new ApiExplorerModelValues(inner.ApiExplorer);
|
||||||
Parameters = inner.Parameters.Select(p => new ParameterModelValues(p)).ToList();
|
Parameters = inner.Parameters.Select(p => new ParameterModelValues(p)).ToList();
|
||||||
|
RouteConstraints = inner.RouteConstraints.Select(
|
||||||
|
r => new RouteConstraintProviderValues(r)).ToList();
|
||||||
Filters = inner.Filters.Select(f => new FilterValues(f)).ToList();
|
Filters = inner.Filters.Select(f => new FilterValues(f)).ToList();
|
||||||
if (inner.AttributeRouteModel != null)
|
if (inner.AttributeRouteModel != null)
|
||||||
{
|
{
|
||||||
|
|
@ -60,6 +62,12 @@ namespace Microsoft.AspNet.Mvc.Logging
|
||||||
/// See <see cref="ActionModel.Filters"/>.
|
/// See <see cref="ActionModel.Filters"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<FilterValues> Filters { get; }
|
public List<FilterValues> Filters { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The route constraints on the controller as <see cref="RouteConstraintProviderValues"/>.
|
||||||
|
/// See <see cref="ControllerModel.RouteConstraints"/>.
|
||||||
|
/// </summary>
|
||||||
|
public List<RouteConstraintProviderValues> RouteConstraints { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The attribute route model of the action as <see cref="AttributeRouteModelValues"/>.
|
/// The attribute route model of the action as <see cref="AttributeRouteModelValues"/>.
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ namespace Microsoft.AspNet.Mvc.Logging
|
||||||
Filters = inner.Filters.Select(f => new FilterValues(f)).ToList();
|
Filters = inner.Filters.Select(f => new FilterValues(f)).ToList();
|
||||||
ActionConstraints = inner.ActionConstraints?.Select(a => new ActionConstraintValues(a))?.ToList();
|
ActionConstraints = inner.ActionConstraints?.Select(a => new ActionConstraintValues(a))?.ToList();
|
||||||
RouteConstraints = inner.RouteConstraints.Select(
|
RouteConstraints = inner.RouteConstraints.Select(
|
||||||
r => new RouteConstraintAttributeValues(r)).ToList();
|
r => new RouteConstraintProviderValues(r)).ToList();
|
||||||
AttributeRoutes = inner.AttributeRoutes.Select(
|
AttributeRoutes = inner.AttributeRoutes.Select(
|
||||||
a => new AttributeRouteModelValues(a)).ToList();
|
a => new AttributeRouteModelValues(a)).ToList();
|
||||||
}
|
}
|
||||||
|
|
@ -72,10 +72,10 @@ namespace Microsoft.AspNet.Mvc.Logging
|
||||||
public List<ActionConstraintValues> ActionConstraints { get; }
|
public List<ActionConstraintValues> ActionConstraints { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The route constraints on the controller as <see cref="RouteConstraintAttributeValues"/>.
|
/// The route constraints on the controller as <see cref="RouteConstraintProviderValues"/>.
|
||||||
/// See <see cref="ControllerModel.RouteConstraints"/>.
|
/// See <see cref="ControllerModel.RouteConstraints"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<RouteConstraintAttributeValues> RouteConstraints { get; set; }
|
public List<RouteConstraintProviderValues> RouteConstraints { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The attribute routes on the controller as <see cref="AttributeRouteModelValues"/>.
|
/// The attribute routes on the controller as <see cref="AttributeRouteModelValues"/>.
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,12 @@ using Microsoft.Framework.Logging;
|
||||||
namespace Microsoft.AspNet.Mvc.Logging
|
namespace Microsoft.AspNet.Mvc.Logging
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Logging representation of a <see cref="RouteConstraintAttribute"/>. Logged as a substructure of
|
/// Logging representation of a <see cref="IRouteConstraintProvider"/>. Logged as a substructure of
|
||||||
/// <see cref="ControllerModelValues"/>
|
/// <see cref="ControllerModelValues"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class RouteConstraintAttributeValues : LoggerStructureBase
|
public class RouteConstraintProviderValues : LoggerStructureBase
|
||||||
{
|
{
|
||||||
public RouteConstraintAttributeValues([NotNull] RouteConstraintAttribute inner)
|
public RouteConstraintProviderValues([NotNull] IRouteConstraintProvider inner)
|
||||||
{
|
{
|
||||||
RouteKey = inner.RouteKey;
|
RouteKey = inner.RouteKey;
|
||||||
RouteValue = inner.RouteValue;
|
RouteValue = inner.RouteValue;
|
||||||
|
|
@ -20,22 +20,22 @@ namespace Microsoft.AspNet.Mvc.Logging
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The route value key. See <see cref="RouteConstraintAttribute.RouteKey"/>.
|
/// The route value key. See <see cref="IRouteConstraintProvider.RouteKey"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string RouteKey { get; }
|
public string RouteKey { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The expected route value. See <see cref="RouteConstraintAttribute.RouteValue"/>.
|
/// The expected route value. See <see cref="IRouteConstraintProvider.RouteValue"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string RouteValue { get; }
|
public string RouteValue { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="RouteKeyHandling"/>. See <see cref="RouteConstraintAttribute.RouteKeyHandling"/>.
|
/// The <see cref="RouteKeyHandling"/>. See <see cref="IRouteConstraintProvider.RouteKeyHandling"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public RouteKeyHandling RouteKeyHandling { get; }
|
public RouteKeyHandling RouteKeyHandling { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// See <see cref="RouteConstraintAttribute.BlockNonAttributedActions"/>.
|
/// See <see cref="IRouteConstraintProvider.BlockNonAttributedActions"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool BlockNonAttributedActions { get; }
|
public bool BlockNonAttributedActions { get; }
|
||||||
|
|
||||||
|
|
@ -44,4 +44,4 @@ namespace Microsoft.AspNet.Mvc.Logging
|
||||||
return LogFormatter.FormatStructure(this);
|
return LogFormatter.FormatStructure(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -15,11 +15,9 @@ namespace Microsoft.AspNet.Mvc
|
||||||
///
|
///
|
||||||
/// When placed on a controller, unless overridden by the action, the constraint applies to all
|
/// When placed on a controller, unless overridden by the action, the constraint applies to all
|
||||||
/// actions defined by the controller.
|
/// actions defined by the controller.
|
||||||
///
|
|
||||||
///
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
|
||||||
public abstract class RouteConstraintAttribute : Attribute
|
public abstract class RouteConstraintAttribute : Attribute, IRouteConstraintProvider
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new <see cref="RouteConstraintAttribute"/>.
|
/// Creates a new <see cref="RouteConstraintAttribute"/>.
|
||||||
|
|
@ -65,25 +63,16 @@ namespace Microsoft.AspNet.Mvc
|
||||||
BlockNonAttributedActions = blockNonAttributedActions;
|
BlockNonAttributedActions = blockNonAttributedActions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// The route value key.
|
|
||||||
/// </summary>
|
|
||||||
public string RouteKey { get; private set; }
|
public string RouteKey { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// The <see cref="RouteKeyHandling"/>.
|
|
||||||
/// </summary>
|
|
||||||
public RouteKeyHandling RouteKeyHandling { get; private set; }
|
public RouteKeyHandling RouteKeyHandling { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// The expected route value. Will be null unless <see cref="RouteConstraintAttribute.RouteKeyHandling"/> is
|
|
||||||
/// set to <see cref="RouteKeyHandling.RequireKey"/>.
|
|
||||||
/// </summary>
|
|
||||||
public string RouteValue { get; private set; }
|
public string RouteValue { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// Set to true to negate this constraint on all actions that do not define a behavior for this route key.
|
|
||||||
/// </summary>
|
|
||||||
public bool BlockNonAttributedActions { get; private set; }
|
public bool BlockNonAttributedActions { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
action.Filters.Add(new AuthorizeAttribute());
|
action.Filters.Add(new AuthorizeAttribute());
|
||||||
action.HttpMethods.Add("GET");
|
action.HttpMethods.Add("GET");
|
||||||
action.IsActionNameMatchRequired = true;
|
action.IsActionNameMatchRequired = true;
|
||||||
|
action.RouteConstraints.Add(new AreaAttribute("Admin"));
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var action2 = new ActionModel(action);
|
var action2 = new ActionModel(action);
|
||||||
|
|
|
||||||
|
|
@ -200,7 +200,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
var expected =
|
var expected =
|
||||||
"While processing template '[area]/[controller]/[action2]', " +
|
"While processing template '[area]/[controller]/[action2]', " +
|
||||||
"a replacement value for the token 'action2' could not be found. " +
|
"a replacement value for the token 'action2' could not be found. " +
|
||||||
"Available tokens: 'area, controller, action'.";
|
"Available tokens: 'action, area, controller'.";
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var ex = Assert.Throws<InvalidOperationException>(
|
var ex = Assert.Throws<InvalidOperationException>(
|
||||||
|
|
|
||||||
|
|
@ -547,7 +547,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
||||||
"For action: 'Microsoft.AspNet.Mvc.Test.ControllerActionDescriptorProviderTests+" +
|
"For action: 'Microsoft.AspNet.Mvc.Test.ControllerActionDescriptorProviderTests+" +
|
||||||
"MultipleErrorsController.Unknown'" + Environment.NewLine +
|
"MultipleErrorsController.Unknown'" + Environment.NewLine +
|
||||||
"Error: While processing template 'stub/[action]/[unknown]', a replacement value for the token 'unknown' " +
|
"Error: While processing template 'stub/[action]/[unknown]', a replacement value for the token 'unknown' " +
|
||||||
"could not be found. Available tokens: 'controller, action'." + Environment.NewLine +
|
"could not be found. Available tokens: 'action, controller'." + Environment.NewLine +
|
||||||
Environment.NewLine +
|
Environment.NewLine +
|
||||||
"Error 2:" + Environment.NewLine +
|
"Error 2:" + Environment.NewLine +
|
||||||
"For action: 'Microsoft.AspNet.Mvc.Test.ControllerActionDescriptorProviderTests+" +
|
"For action: 'Microsoft.AspNet.Mvc.Test.ControllerActionDescriptorProviderTests+" +
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Logging
|
namespace Microsoft.AspNet.Mvc.Logging
|
||||||
{
|
{
|
||||||
public class RouteConstraintAttributeValuesTest
|
public class RouteConstraintProviderValuesTest
|
||||||
{
|
{
|
||||||
[Fact]
|
[Fact]
|
||||||
public void RouteConstraintAttributeValues_IncludesAllProperties()
|
public void RouteConstraintProviderValues_IncludesAllProperties()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var exclude = new[] { "TypeId" };
|
var exclude = new[] { "TypeId" };
|
||||||
|
|
@ -16,7 +16,7 @@ namespace Microsoft.AspNet.Mvc.Logging
|
||||||
// Assert
|
// Assert
|
||||||
PropertiesAssert.PropertiesAreTheSame(
|
PropertiesAssert.PropertiesAreTheSame(
|
||||||
typeof(RouteConstraintAttribute),
|
typeof(RouteConstraintAttribute),
|
||||||
typeof(RouteConstraintAttributeValues),
|
typeof(RouteConstraintProviderValues),
|
||||||
exclude);
|
exclude);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue