Adding Remaining Inline Route Constraints.
This commit is contained in:
parent
0ca5576926
commit
fbffcb7b40
|
|
@ -45,11 +45,11 @@ namespace RoutingSample.Web
|
|||
routeBuilder.MapRoute("regexStringRoute",
|
||||
"api/rconstraint/{controller}",
|
||||
new { foo = "Bar" },
|
||||
new { controller = new RegexConstraint("^(my.*)$") });
|
||||
new { controller = new RegexRouteConstraint("^(my.*)$") });
|
||||
routeBuilder.MapRoute("regexRoute",
|
||||
"api/r2constraint/{controller}",
|
||||
new { foo = "Bar2" },
|
||||
new { controller = new RegexConstraint(new Regex("^(my.*)$")) });
|
||||
new { controller = new RegexRouteConstraint(new Regex("^(my.*)$")) });
|
||||
|
||||
routeBuilder.MapRoute("parameterConstraintRoute",
|
||||
"api/{controller}/{*extra}",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
// 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.Routing.Constraints
|
||||
{
|
||||
/// <summary>
|
||||
/// Constrains a route parameter to contain only lowercase or uppercase letters A through Z in the English alphabet.
|
||||
/// </summary>
|
||||
public class AlphaRouteConstraint : RegexRouteConstraint
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AlphaRouteConstraint" /> class.
|
||||
/// </summary>
|
||||
public AlphaRouteConstraint() : base(@"^[a-z]*$")
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Constraints
|
||||
{
|
||||
/// <summary>
|
||||
/// Constrains a route parameter to represent only Boolean values.
|
||||
/// </summary>
|
||||
public class BoolRouteConstraint : IRouteConstraint
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public bool Match([NotNull] HttpContext httpContext,
|
||||
[NotNull] IRouter route,
|
||||
[NotNull] string routeKey,
|
||||
[NotNull] IDictionary<string, object> values,
|
||||
RouteDirection routeDirection)
|
||||
{
|
||||
object value;
|
||||
if (values.TryGetValue(routeKey, out value) && value != null)
|
||||
{
|
||||
if (value is bool)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool result;
|
||||
var valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
return Boolean.TryParse(valueString, out result);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Constraints
|
||||
{
|
||||
/// <summary>
|
||||
/// Constrains a route parameter to represent only <see cref="DateTime"/> values.
|
||||
/// Supports date time formats represented by CultureInfo.DateTimeFormat for the CultureInfo.InvariantCulture.
|
||||
/// </summary>
|
||||
public class DateTimeRouteConstraint : IRouteConstraint
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public bool Match([NotNull] HttpContext httpContext,
|
||||
[NotNull] IRouter route,
|
||||
[NotNull] string routeKey,
|
||||
[NotNull] IDictionary<string, object> values,
|
||||
RouteDirection routeDirection)
|
||||
{
|
||||
object value;
|
||||
if (values.TryGetValue(routeKey, out value) && value != null)
|
||||
{
|
||||
if (value is DateTime)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
DateTime result;
|
||||
var valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
return DateTime.TryParse(valueString, CultureInfo.InvariantCulture, DateTimeStyles.None, out result);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Constraints
|
||||
{
|
||||
/// <summary>
|
||||
/// Constrains a route parameter to represent only decimal values.
|
||||
/// </summary>
|
||||
public class DecimalRouteConstraint : IRouteConstraint
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public bool Match([NotNull] HttpContext httpContext,
|
||||
[NotNull] IRouter route,
|
||||
[NotNull] string routeKey,
|
||||
[NotNull] IDictionary<string, object> values,
|
||||
RouteDirection routeDirection)
|
||||
{
|
||||
object value;
|
||||
if (values.TryGetValue(routeKey, out value) && value != null)
|
||||
{
|
||||
if (value is decimal)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
decimal result;
|
||||
var valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
return Decimal.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out result);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Constraints
|
||||
{
|
||||
/// <summary>
|
||||
/// Constrains a route parameter to represent only 64-bit floating-point values.
|
||||
/// </summary>
|
||||
public class DoubleRouteConstraint : IRouteConstraint
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public bool Match([NotNull] HttpContext httpContext,
|
||||
[NotNull] IRouter route,
|
||||
[NotNull] string routeKey,
|
||||
[NotNull] IDictionary<string, object> values,
|
||||
RouteDirection routeDirection)
|
||||
{
|
||||
object value;
|
||||
if (values.TryGetValue(routeKey, out value) && value != null)
|
||||
{
|
||||
if (value is double)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
double result;
|
||||
var valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
return Double.TryParse(valueString,
|
||||
NumberStyles.Float | NumberStyles.AllowThousands,
|
||||
CultureInfo.InvariantCulture,
|
||||
out result);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Constraints
|
||||
{
|
||||
/// <summary>
|
||||
/// Constrains a route parameter to represent only 32-bit floating-point values.
|
||||
/// </summary>
|
||||
public class FloatRouteConstraint : IRouteConstraint
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public bool Match([NotNull] HttpContext httpContext,
|
||||
[NotNull] IRouter route,
|
||||
[NotNull] string routeKey,
|
||||
[NotNull] IDictionary<string, object> values,
|
||||
RouteDirection routeDirection)
|
||||
{
|
||||
object value;
|
||||
if (values.TryGetValue(routeKey, out value) && value != null)
|
||||
{
|
||||
if (value is float)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
float result;
|
||||
var valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
return Single.TryParse(valueString,
|
||||
NumberStyles.Float | NumberStyles.AllowThousands,
|
||||
CultureInfo.InvariantCulture,
|
||||
out result);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Constraints
|
||||
{
|
||||
/// <summary>
|
||||
/// Constrains a route parameter to represent only <see cref="Guid"/> values.
|
||||
/// Matches values specified in any of the five formats "N", "D", "B", "P", or "X",
|
||||
/// supported by Guid.ToString(string) and Guid.ToString(String, IFormatProvider) methods.
|
||||
/// </summary>
|
||||
public class GuidRouteConstraint : IRouteConstraint
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public bool Match([NotNull] HttpContext httpContext,
|
||||
[NotNull] IRouter route,
|
||||
[NotNull] string routeKey,
|
||||
[NotNull] IDictionary<string, object> values,
|
||||
RouteDirection routeDirection)
|
||||
{
|
||||
object value;
|
||||
if (values.TryGetValue(routeKey, out value) && value != null)
|
||||
{
|
||||
if (value is Guid)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Guid result;
|
||||
var valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
return Guid.TryParse(valueString, out result);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Constraints
|
||||
{
|
||||
/// <summary>
|
||||
/// Constrains a route parameter to be a string of a given length or within a given range of lengths.
|
||||
/// </summary>
|
||||
public class LengthRouteConstraint : IRouteConstraint
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LengthRouteConstraint" /> class that constrains
|
||||
/// a route parameter to be a string of a given length.
|
||||
/// </summary>
|
||||
/// <param name="length">The length of the route parameter.</param>
|
||||
public LengthRouteConstraint(int length)
|
||||
{
|
||||
if (length < 0)
|
||||
{
|
||||
var errorMessage = Resources.FormatArgumentMustBeGreaterThanOrEqualTo(0);
|
||||
throw new ArgumentOutOfRangeException("length", length, errorMessage);
|
||||
}
|
||||
|
||||
MinLength = MaxLength = length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LengthRouteConstraint" /> class that constrains
|
||||
/// a route parameter to be a string of a given length.
|
||||
/// </summary>
|
||||
/// <param name="minLength">The minimum length allowed for the route parameter.</param>
|
||||
/// <param name="maxLength">The maximum length allowed for the route parameter.</param>
|
||||
public LengthRouteConstraint(int minLength, int maxLength)
|
||||
{
|
||||
if (minLength < 0)
|
||||
{
|
||||
var errorMessage = Resources.FormatArgumentMustBeGreaterThanOrEqualTo(0);
|
||||
throw new ArgumentOutOfRangeException("minLength", minLength, errorMessage);
|
||||
}
|
||||
|
||||
if (maxLength < 0)
|
||||
{
|
||||
var errorMessage = Resources.FormatArgumentMustBeGreaterThanOrEqualTo(0);
|
||||
throw new ArgumentOutOfRangeException("maxLength", maxLength, errorMessage);
|
||||
}
|
||||
|
||||
if (minLength > maxLength)
|
||||
{
|
||||
var errorMessage =
|
||||
Resources.FormatRangeConstraint_MinShouldBeLessThanOrEqualToMax("minLength", "maxLength");
|
||||
throw new ArgumentOutOfRangeException("minLength", minLength, errorMessage);
|
||||
}
|
||||
|
||||
MinLength = minLength;
|
||||
MaxLength = maxLength;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the minimum length allowed for the route parameter.
|
||||
/// </summary>
|
||||
public int MinLength { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the maximum length allowed for the route parameter.
|
||||
/// </summary>
|
||||
public int MaxLength { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Match([NotNull] HttpContext httpContext,
|
||||
[NotNull] IRouter route,
|
||||
[NotNull] string routeKey,
|
||||
[NotNull] IDictionary<string, object> values,
|
||||
RouteDirection routeDirection)
|
||||
{
|
||||
object value;
|
||||
if (values.TryGetValue(routeKey, out value) && value != null)
|
||||
{
|
||||
var valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
var length = valueString.Length;
|
||||
return length >= MinLength && length <= MaxLength;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Constraints
|
||||
{
|
||||
/// <summary>
|
||||
/// Constrains a route parameter to represent only 64-bit integer values.
|
||||
/// </summary>
|
||||
public class LongRouteConstraint : IRouteConstraint
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public bool Match([NotNull] HttpContext httpContext,
|
||||
[NotNull] IRouter route,
|
||||
[NotNull] string routeKey,
|
||||
[NotNull] IDictionary<string, object> values,
|
||||
RouteDirection routeDirection)
|
||||
{
|
||||
object value;
|
||||
if (values.TryGetValue(routeKey, out value) && value != null)
|
||||
{
|
||||
if (value is long)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
long result;
|
||||
var valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
return Int64.TryParse(valueString, NumberStyles.Integer, CultureInfo.InvariantCulture, out result);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Constraints
|
||||
{
|
||||
/// <summary>
|
||||
/// Constrains a route parameter to be a string with a maximum length.
|
||||
/// </summary>
|
||||
public class MaxLengthRouteConstraint : IRouteConstraint
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MaxLengthRouteConstraint" /> class.
|
||||
/// </summary>
|
||||
/// <param name="maxLength">The maximum length allowed for the route parameter.</param>
|
||||
public MaxLengthRouteConstraint(int maxLength)
|
||||
{
|
||||
if (maxLength < 0)
|
||||
{
|
||||
var errorMessage = Resources.FormatArgumentMustBeGreaterThanOrEqualTo(0);
|
||||
throw new ArgumentOutOfRangeException("maxLength", maxLength, errorMessage);
|
||||
}
|
||||
|
||||
MaxLength = maxLength;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the maximum length allowed for the route parameter.
|
||||
/// </summary>
|
||||
public int MaxLength { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Match([NotNull] HttpContext httpContext,
|
||||
[NotNull] IRouter route,
|
||||
[NotNull] string routeKey,
|
||||
[NotNull] IDictionary<string, object> values,
|
||||
RouteDirection routeDirection)
|
||||
{
|
||||
object value;
|
||||
if (values.TryGetValue(routeKey, out value) && value != null)
|
||||
{
|
||||
var valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
return valueString.Length <= MaxLength;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Constraints
|
||||
{
|
||||
/// <summary>
|
||||
/// Constrains a route parameter to be an integer with a maximum value.
|
||||
/// </summary>
|
||||
public class MaxRouteConstraint : IRouteConstraint
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MaxRouteConstraint" /> class.
|
||||
/// </summary>
|
||||
/// <param name="max">The maximum value allowed for the route parameter.</param>
|
||||
public MaxRouteConstraint(long max)
|
||||
{
|
||||
Max = max;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the maximum allowed value of the route parameter.
|
||||
/// </summary>
|
||||
public long Max { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Match([NotNull] HttpContext httpContext,
|
||||
[NotNull] IRouter route,
|
||||
[NotNull] string routeKey,
|
||||
[NotNull] IDictionary<string, object> values,
|
||||
RouteDirection routeDirection)
|
||||
{
|
||||
object value;
|
||||
if (values.TryGetValue(routeKey, out value) && value != null)
|
||||
{
|
||||
long longValue;
|
||||
var valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
if (Int64.TryParse(valueString, NumberStyles.Integer, CultureInfo.InvariantCulture, out longValue))
|
||||
{
|
||||
return longValue <= Max;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Constraints
|
||||
{
|
||||
/// <summary>
|
||||
/// Constrains a route parameter to be a string with a minimum length.
|
||||
/// </summary>
|
||||
public class MinLengthRouteConstraint : IRouteConstraint
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MinLengthRouteConstraint" /> class.
|
||||
/// </summary>
|
||||
/// <param name="minLength">The minimum length allowed for the route parameter.</param>
|
||||
public MinLengthRouteConstraint(int minLength)
|
||||
{
|
||||
if (minLength < 0)
|
||||
{
|
||||
var errorMessage = Resources.FormatArgumentMustBeGreaterThanOrEqualTo(0);
|
||||
throw new ArgumentOutOfRangeException("minLength", minLength, errorMessage);
|
||||
}
|
||||
|
||||
MinLength = minLength;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the minimum length allowed for the route parameter.
|
||||
/// </summary>
|
||||
public int MinLength { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Match([NotNull] HttpContext httpContext,
|
||||
[NotNull] IRouter route,
|
||||
[NotNull] string routeKey,
|
||||
[NotNull] IDictionary<string, object> values,
|
||||
RouteDirection routeDirection)
|
||||
{
|
||||
object value;
|
||||
if (values.TryGetValue(routeKey, out value) && value != null)
|
||||
{
|
||||
var valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
return valueString.Length >= MinLength;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Constraints
|
||||
{
|
||||
/// <summary>
|
||||
/// Constrains a route parameter to be a long with a minimum value.
|
||||
/// </summary>
|
||||
public class MinRouteConstraint : IRouteConstraint
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MinRouteConstraint" /> class.
|
||||
/// </summary>
|
||||
/// <param name="min">The minimum value allowed for the route parameter.</param>
|
||||
public MinRouteConstraint(long min)
|
||||
{
|
||||
Min = min;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the minimum allowed value of the route parameter.
|
||||
/// </summary>
|
||||
public long Min { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Match([NotNull] HttpContext httpContext,
|
||||
[NotNull] IRouter route,
|
||||
[NotNull] string routeKey,
|
||||
[NotNull] IDictionary<string, object> values,
|
||||
RouteDirection routeDirection)
|
||||
{
|
||||
object value;
|
||||
if (values.TryGetValue(routeKey, out value) && value != null)
|
||||
{
|
||||
long longValue;
|
||||
var valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
if (Int64.TryParse(valueString, NumberStyles.Integer, CultureInfo.InvariantCulture, out longValue))
|
||||
{
|
||||
return longValue >= Min;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Constraints
|
||||
{
|
||||
/// <summary>
|
||||
/// Constraints a route parameter to be an integer within a given range of values.
|
||||
/// </summary>
|
||||
public class RangeRouteConstraint : IRouteConstraint
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RangeRouteConstraint" /> class.
|
||||
/// </summary>
|
||||
/// <param name="min">The minimum value.</param>
|
||||
/// <param name="max">The maximum value.</param>
|
||||
/// <remarks>The minimum value should be less than or equal to the maximum value.</remarks>
|
||||
public RangeRouteConstraint(long min, long max)
|
||||
{
|
||||
if (min > max)
|
||||
{
|
||||
var errorMessage = Resources.FormatRangeConstraint_MinShouldBeLessThanOrEqualToMax("min", "max");
|
||||
throw new ArgumentOutOfRangeException("min", min, errorMessage);
|
||||
}
|
||||
|
||||
Min = min;
|
||||
Max = max;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the minimum allowed value of the route parameter.
|
||||
/// </summary>
|
||||
public long Min { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the maximum allowed value of the route parameter.
|
||||
/// </summary>
|
||||
public long Max { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Match([NotNull] HttpContext httpContext,
|
||||
[NotNull] IRouter route,
|
||||
[NotNull] string routeKey,
|
||||
[NotNull] IDictionary<string, object> values,
|
||||
RouteDirection routeDirection)
|
||||
{
|
||||
object value;
|
||||
if (values.TryGetValue(routeKey, out value) && value != null)
|
||||
{
|
||||
long longValue;
|
||||
var valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
if (Int64.TryParse(valueString, NumberStyles.Integer, CultureInfo.InvariantCulture, out longValue))
|
||||
{
|
||||
return longValue >= Min && longValue <= Max;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,14 +9,14 @@ using Microsoft.AspNet.Http;
|
|||
|
||||
namespace Microsoft.AspNet.Routing.Constraints
|
||||
{
|
||||
public class RegexConstraint : IRouteConstraint
|
||||
public class RegexRouteConstraint : IRouteConstraint
|
||||
{
|
||||
public RegexConstraint([NotNull] Regex regex)
|
||||
public RegexRouteConstraint([NotNull] Regex regex)
|
||||
{
|
||||
Constraint = regex;
|
||||
}
|
||||
|
||||
public RegexConstraint([NotNull] string regexPattern)
|
||||
public RegexRouteConstraint([NotNull] string regexPattern)
|
||||
{
|
||||
Constraint = new Regex(regexPattern, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
|
||||
}
|
||||
|
|
@ -102,7 +102,7 @@ namespace Microsoft.AspNet.Routing
|
|||
{
|
||||
throw new InvalidOperationException(
|
||||
Resources.FormatDefaultInlineConstraintResolver_CouldNotFindCtor(
|
||||
constraintTypeInfo.Name, argumentString.Length));
|
||||
constraintTypeInfo.Name, arguments.Length));
|
||||
}
|
||||
else if (constructorMatches == 1)
|
||||
{
|
||||
|
|
@ -113,7 +113,7 @@ namespace Microsoft.AspNet.Routing
|
|||
{
|
||||
throw new InvalidOperationException(
|
||||
Resources.FormatDefaultInlineConstraintResolver_AmbiguousCtors(
|
||||
constraintTypeInfo.Name, argumentString.Length));
|
||||
constraintTypeInfo.Name, arguments.Length));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,18 +78,18 @@ namespace Microsoft.AspNet.Routing
|
|||
}
|
||||
|
||||
private static IRouteConstraint GetInlineConstraint(Group constraintGroup,
|
||||
IInlineConstraintResolver constraintResolver)
|
||||
IInlineConstraintResolver _constraintResolver)
|
||||
{
|
||||
var parameterConstraints = new List<IRouteConstraint>();
|
||||
foreach (Capture constraintCapture in constraintGroup.Captures)
|
||||
{
|
||||
var inlineConstraint = constraintCapture.Value;
|
||||
var constraint = constraintResolver.ResolveConstraint(inlineConstraint);
|
||||
var constraint = _constraintResolver.ResolveConstraint(inlineConstraint);
|
||||
if (constraint == null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
Resources.FormatInlineRouteParser_CouldNotResolveConstraint(
|
||||
constraintResolver.GetType().Name, inlineConstraint));
|
||||
_constraintResolver.GetType().Name, inlineConstraint));
|
||||
}
|
||||
|
||||
parameterConstraints.Add(constraint);
|
||||
|
|
|
|||
|
|
@ -25,8 +25,22 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="BuilderExtensions.cs" />
|
||||
<Compile Include="Constraints\CompositeRouteConstraint.cs" />
|
||||
<Compile Include="Constraints\DateTimeRouteConstraint.cs" />
|
||||
<Compile Include="Constraints\DoubleRouteConstraint.cs" />
|
||||
<Compile Include="Constraints\DecimalRouteConstraint.cs" />
|
||||
<Compile Include="Constraints\FloatRouteConstraint.cs" />
|
||||
<Compile Include="Constraints\GuidRouteConstraint.cs" />
|
||||
<Compile Include="Constraints\AlphaRouteConstraint.cs" />
|
||||
<Compile Include="Constraints\LongRouteConstraint.cs" />
|
||||
<Compile Include="Constraints\MaxLengthRouteConstraint.cs" />
|
||||
<Compile Include="Constraints\MaxRouteConstraint.cs" />
|
||||
<Compile Include="Constraints\MinLengthRouteConstraint.cs" />
|
||||
<Compile Include="Constraints\RangeRouteConstraint.cs" />
|
||||
<Compile Include="Constraints\MinRouteConstraint.cs" />
|
||||
<Compile Include="Constraints\LengthRouteConstraint.cs" />
|
||||
<Compile Include="Constraints\BoolRouteConstraint.cs" />
|
||||
<Compile Include="Constraints\IntRouteConstraint.cs" />
|
||||
<Compile Include="Constraints\RegexConstraint.cs" />
|
||||
<Compile Include="Constraints\RegexRouteConstraint.cs" />
|
||||
<Compile Include="DefaultInlineConstraintResolver.cs" />
|
||||
<Compile Include="IInlineConstraintResolver.cs" />
|
||||
<Compile Include="INamedRouter.cs" />
|
||||
|
|
@ -46,9 +60,9 @@
|
|||
<Compile Include="RouteContext.cs" />
|
||||
<Compile Include="RouteData.cs" />
|
||||
<Compile Include="RouteDirection.cs" />
|
||||
<Compile Include="RouterServices.cs" />
|
||||
<Compile Include="RouterMiddleware.cs" />
|
||||
<Compile Include="RouteValueDictionary.cs" />
|
||||
<Compile Include="RoutingServices.cs" />
|
||||
<Compile Include="Template\Template.cs" />
|
||||
<Compile Include="Template\TemplateBinder.cs" />
|
||||
<Compile Include="Template\TemplateMatcher.cs" />
|
||||
|
|
|
|||
|
|
@ -10,6 +10,38 @@ namespace Microsoft.AspNet.Routing
|
|||
private static readonly ResourceManager _resourceManager
|
||||
= new ResourceManager("Microsoft.AspNet.Routing.Resources", typeof(Resources).GetTypeInfo().Assembly);
|
||||
|
||||
/// <summary>
|
||||
/// Value must be greater than or equal to {0}.
|
||||
/// </summary>
|
||||
internal static string ArgumentMustBeGreaterThanOrEqualTo
|
||||
{
|
||||
get { return GetString("ArgumentMustBeGreaterThanOrEqualTo"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Value must be greater than or equal to {0}.
|
||||
/// </summary>
|
||||
internal static string FormatArgumentMustBeGreaterThanOrEqualTo(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("ArgumentMustBeGreaterThanOrEqualTo"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The value for argument '{0}' should be less than or equal to the value for the argument '{1}'.
|
||||
/// </summary>
|
||||
internal static string RangeConstraint_MinShouldBeLessThanOrEqualToMax
|
||||
{
|
||||
get { return GetString("RangeConstraint_MinShouldBeLessThanOrEqualToMax"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The value for argument '{0}' should be less than or equal to the value for the argument '{1}'.
|
||||
/// </summary>
|
||||
internal static string FormatRangeConstraint_MinShouldBeLessThanOrEqualToMax(object p0, object p1)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("RangeConstraint_MinShouldBeLessThanOrEqualToMax"), p0, p1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The '{0}' property of '{1}' must not be null.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -117,6 +117,12 @@
|
|||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ArgumentMustBeGreaterThanOrEqualTo" xml:space="preserve">
|
||||
<value>Value must be greater than or equal to {0}.</value>
|
||||
</data>
|
||||
<data name="RangeConstraint_MinShouldBeLessThanOrEqualToMax" xml:space="preserve">
|
||||
<value>The value for argument '{0}' should be less than or equal to the value for the argument '{1}'.</value>
|
||||
</data>
|
||||
<data name="PropertyOfTypeCannotBeNull" xml:space="preserve">
|
||||
<value>The '{0}' property of '{1}' must not be null.</value>
|
||||
</data>
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ namespace Microsoft.AspNet.Routing
|
|||
|
||||
var constraintsRegEx = "^(" + regexPattern + ")$";
|
||||
|
||||
constraint = new RegexConstraint(constraintsRegEx);
|
||||
constraint = new RegexRouteConstraint(constraintsRegEx);
|
||||
}
|
||||
|
||||
constraints.Add(kvp.Key, constraint);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,26 @@ namespace Microsoft.AspNet.Routing
|
|||
{
|
||||
// Type-specific constraints
|
||||
{ "int", typeof(IntRouteConstraint) },
|
||||
{ "bool", typeof(BoolRouteConstraint) },
|
||||
{ "datetime", typeof(DateTimeRouteConstraint) },
|
||||
{ "decimal", typeof(DecimalRouteConstraint) },
|
||||
{ "double", typeof(DoubleRouteConstraint) },
|
||||
{ "float", typeof(FloatRouteConstraint) },
|
||||
{ "guid", typeof(GuidRouteConstraint) },
|
||||
{ "long", typeof(LongRouteConstraint) },
|
||||
|
||||
// Length constraints
|
||||
{ "minlength", typeof(MinLengthRouteConstraint) },
|
||||
{ "maxlength", typeof(MaxLengthRouteConstraint) },
|
||||
{ "length", typeof(LengthRouteConstraint) },
|
||||
|
||||
// Min/Max value constraints
|
||||
{ "min", typeof(MinRouteConstraint) },
|
||||
{ "max", typeof(MaxRouteConstraint) },
|
||||
{ "range", typeof(RangeRouteConstraint) },
|
||||
|
||||
// Regex-based constraints
|
||||
{ "alpha", typeof(AlphaRouteConstraint) },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
// 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.
|
||||
|
||||
#if NET45
|
||||
|
||||
using Microsoft.AspNet.Routing.Constraints;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public class AlphaRouteConstraintTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("alpha", true)]
|
||||
[InlineData("a1pha", false)]
|
||||
[InlineData("ALPHA", true)]
|
||||
[InlineData("A1PHA", false)]
|
||||
[InlineData("alPHA", true)]
|
||||
[InlineData("A1pHA", false)]
|
||||
[InlineData("AlpHA╥", false)]
|
||||
[InlineData("", true)]
|
||||
public void AlphaRouteConstraintTest(string parameterValue, bool expected)
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new AlphaRouteConstraint();
|
||||
|
||||
// Act
|
||||
var actual = ConstraintsTestHelper.TestConstraint(constraint, parameterValue);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
// 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.
|
||||
|
||||
#if NET45
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Routing.Constraints;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public class BoolRouteConstraintTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("true", true)]
|
||||
[InlineData("TruE", true)]
|
||||
[InlineData("false", true)]
|
||||
[InlineData("FalSe", true)]
|
||||
[InlineData(" FalSe", true)]
|
||||
[InlineData("True ", true)]
|
||||
[InlineData(" False ", true)]
|
||||
[InlineData(true, true)]
|
||||
[InlineData(false, true)]
|
||||
[InlineData(1, false)]
|
||||
[InlineData("not-parseable-as-bool", false)]
|
||||
public void BoolRouteConstraint(object parameterValue, bool expected)
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new BoolRouteConstraint();
|
||||
|
||||
// Act
|
||||
var actual = ConstraintsTestHelper.TestConstraint(constraint, parameterValue);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -7,38 +7,19 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Routing.Constraints;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public class RouteConstraintsTests
|
||||
public class CompositeRouteConstraintTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(42, true)]
|
||||
[InlineData("42", true)]
|
||||
[InlineData(3.14, false)]
|
||||
[InlineData("43.567", false)]
|
||||
[InlineData("42a", false)]
|
||||
public void IntRouteConstraint_Match_AppliesConstraint(object parameterValue, bool expected)
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new IntRouteConstraint();
|
||||
|
||||
// Act
|
||||
var actual = TestValue(constraint, parameterValue);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true, true, true)]
|
||||
[InlineData(true, false, false)]
|
||||
[InlineData(false, true, false)]
|
||||
[InlineData(false, false, false)]
|
||||
public void CompoundRouteConstraint_Match_CallsMatchOnInnerConstraints(bool inner1Result,
|
||||
public void CompositeRouteConstraint_Match_CallsMatchOnInnerConstraints(bool inner1Result,
|
||||
bool inner2Result,
|
||||
bool expected)
|
||||
{
|
||||
|
|
@ -48,7 +29,7 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
|
||||
// Act
|
||||
var constraint = new CompositeRouteConstraint(new[] { inner1.Object, inner2.Object });
|
||||
var actual = TestValue(constraint, null);
|
||||
var actual = ConstraintsTestHelper.TestConstraint(constraint, null);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual);
|
||||
|
|
@ -69,28 +50,6 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
.Verifiable();
|
||||
return mock;
|
||||
}
|
||||
|
||||
private static void AssertMatchWasCalled(Mock<IRouteConstraint> mock, Times times)
|
||||
{
|
||||
mock.Verify(ConstraintMatchMethodExpression, times);
|
||||
}
|
||||
|
||||
private static bool TestValue(IRouteConstraint constraint, object value, Action<IRouter> routeConfig = null)
|
||||
{
|
||||
var context = new Mock<HttpContext>();
|
||||
|
||||
IRouter route = new RouteCollection();
|
||||
|
||||
if (routeConfig != null)
|
||||
{
|
||||
routeConfig(route);
|
||||
}
|
||||
|
||||
var parameterName = "fake";
|
||||
var values = new Dictionary<string, object>() { { parameterName, value } };
|
||||
var routeDirection = RouteDirection.IncomingRequest;
|
||||
return constraint.Match(context.Object, route, parameterName, values, routeDirection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
// 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.
|
||||
|
||||
#if NET45
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Moq;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public class ConstraintsTestHelper
|
||||
{
|
||||
public static bool TestConstraint(IRouteConstraint constraint, object value, Action<IRouter> routeConfig = null)
|
||||
{
|
||||
var context = new Mock<HttpContext>();
|
||||
|
||||
var route = new RouteCollection();
|
||||
|
||||
if (routeConfig != null)
|
||||
{
|
||||
routeConfig(route);
|
||||
}
|
||||
|
||||
var parameterName = "fake";
|
||||
var values = new Dictionary<string, object>() { { parameterName, value } };
|
||||
var routeDirection = RouteDirection.IncomingRequest;
|
||||
return constraint.Match(context.Object, route, parameterName, values, routeDirection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
// 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.
|
||||
|
||||
#if NET45
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNet.Routing.Constraints;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public class DateTimeRouteConstraintTests
|
||||
{
|
||||
public static IEnumerable<object[]> GetDateTimeObject
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new object[]
|
||||
{
|
||||
DateTime.Now,
|
||||
true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("12/25/2009", true)]
|
||||
[InlineData("25/12/2009 11:45:00 PM", false)]
|
||||
[InlineData("25/12/2009", false)]
|
||||
[InlineData("11:45:00 PM", true)]
|
||||
[InlineData("11:45:00", true)]
|
||||
[InlineData("11:45", true)]
|
||||
[InlineData("11", false)]
|
||||
[InlineData("", false)]
|
||||
[InlineData("Apr 5 2009 11:45:00 PM", true)]
|
||||
[InlineData("April 5 2009 11:45:00 PM", true)]
|
||||
[InlineData("12/25/2009 11:45:00 PM", true)]
|
||||
[InlineData("11:45:00 PM", true)]
|
||||
[InlineData("2009-05-12T11:45:00Z", true)]
|
||||
[InlineData("not-parseable-as-date", false)]
|
||||
[InlineData(false, false)]
|
||||
[MemberData("GetDateTimeObject")]
|
||||
public void DateTimeRouteConstraint(object parameterValue, bool expected)
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new DateTimeRouteConstraint();
|
||||
|
||||
// Act
|
||||
var actual = ConstraintsTestHelper.TestConstraint(constraint, parameterValue);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
// 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.
|
||||
|
||||
#if NET45
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNet.Routing.Constraints;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public class DecimalRouteConstraintTests
|
||||
{
|
||||
public static IEnumerable<object[]> GetDecimalObject
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new object[]
|
||||
{
|
||||
2m,
|
||||
true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("3.14", true)]
|
||||
[InlineData("9223372036854775808.9223372036854775808", true)]
|
||||
[InlineData("1.79769313486232E+300", false)]
|
||||
[InlineData("not-parseable-as-decimal", false)]
|
||||
[InlineData(false, false)]
|
||||
[MemberData("GetDecimalObject")]
|
||||
public void DecimalRouteConstraint_ApplyConstraint(object parameterValue, bool expected)
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new DecimalRouteConstraint();
|
||||
|
||||
// Act
|
||||
var actual = ConstraintsTestHelper.TestConstraint(constraint, parameterValue);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
// 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.
|
||||
|
||||
#if NET45
|
||||
|
||||
using Microsoft.AspNet.Routing.Constraints;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public class DoubleRouteConstraintTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("3.14", true)]
|
||||
[InlineData(3.14f, true)]
|
||||
[InlineData(3.14d, true)]
|
||||
[InlineData("1.79769313486232E+300", true)]
|
||||
[InlineData("not-parseable-as-double", false)]
|
||||
[InlineData(false, false)]
|
||||
public void DoubleRouteConstraint_ApplyConstraint(object parameterValue, bool expected)
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new DoubleRouteConstraint();
|
||||
|
||||
// Act
|
||||
var actual = ConstraintsTestHelper.TestConstraint(constraint, parameterValue);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -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.
|
||||
|
||||
#if NET45
|
||||
|
||||
using Microsoft.AspNet.Routing.Constraints;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public class FloatRouteConstraintTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("3.14", true)]
|
||||
[InlineData(3.14, true)]
|
||||
[InlineData("not-parseable-as-float", false)]
|
||||
[InlineData(false, false)]
|
||||
[InlineData("1.79769313486232E+300", false)]
|
||||
public void FloatRouteConstraint_ApplyConstraint(object parameterValue, bool expected)
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new FloatRouteConstraint();
|
||||
|
||||
// Act
|
||||
var actual = ConstraintsTestHelper.TestConstraint(constraint, parameterValue);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
// 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.
|
||||
|
||||
#if NET45
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNet.Routing.Constraints;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public class GuidRouteConstraintTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("12345678-1234-1234-1234-123456789012", false, true)]
|
||||
[InlineData("12345678-1234-1234-1234-123456789012", true, true)]
|
||||
[InlineData("12345678901234567890123456789012", false, true)]
|
||||
[InlineData("not-parseable-as-guid", false, false)]
|
||||
[InlineData(12, false, false)]
|
||||
|
||||
public void GuidRouteConstraint_ApplyConstraint(object parameterValue, bool parseBeforeTest, bool expected)
|
||||
{
|
||||
// Arrange
|
||||
if (parseBeforeTest)
|
||||
{
|
||||
parameterValue = Guid.Parse(parameterValue.ToString());
|
||||
}
|
||||
|
||||
var constraint = new GuidRouteConstraint();
|
||||
|
||||
// Act
|
||||
var actual = ConstraintsTestHelper.TestConstraint(constraint, parameterValue);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -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.
|
||||
|
||||
#if NET45
|
||||
|
||||
using Microsoft.AspNet.Routing.Constraints;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public class IntRouteConstraintsTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(42, true)]
|
||||
[InlineData("42", true)]
|
||||
[InlineData(3.14, false)]
|
||||
[InlineData("43.567", false)]
|
||||
[InlineData("42a", false)]
|
||||
public void IntRouteConstraint_Match_AppliesConstraint(object parameterValue, bool expected)
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new IntRouteConstraint();
|
||||
|
||||
// Act
|
||||
var actual = ConstraintsTestHelper.TestConstraint(constraint, parameterValue);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
// 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.
|
||||
|
||||
#if NET45
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNet.Routing.Constraints;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public class LengthRouteConstraintTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(3, "123", true)]
|
||||
[InlineData(3, "1234", false)]
|
||||
[InlineData(0, "", true)]
|
||||
public void LengthRouteConstraint_ExactLength_Tests(int length, string parameterValue, bool expected)
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new LengthRouteConstraint(length);
|
||||
|
||||
// Act
|
||||
var actual = ConstraintsTestHelper.TestConstraint(constraint, parameterValue);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(3, 5, "12", false)]
|
||||
[InlineData(3, 5, "123", true)]
|
||||
[InlineData(3, 5, "1234", true)]
|
||||
[InlineData(3, 5, "12345", true)]
|
||||
[InlineData(3, 5, "123456", false)]
|
||||
public void LengthRouteConstraint_Range_Tests(int min, int max, string parameterValue, bool expected)
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new LengthRouteConstraint(min, max);
|
||||
|
||||
// Act
|
||||
var actual = ConstraintsTestHelper.TestConstraint(constraint, parameterValue);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LengthRouteConstraint_SettingLengthLessThanZero_Throws()
|
||||
{
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<ArgumentOutOfRangeException>(() => new LengthRouteConstraint(-1));
|
||||
Assert.Equal("Value must be greater than or equal to 0.\r\nParameter name: length\r\n" +
|
||||
"Actual value was -1.",
|
||||
ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LengthRouteConstraint_SettingMinLengthLessThanZero_Throws()
|
||||
{
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<ArgumentOutOfRangeException>(() => new LengthRouteConstraint(-1, 3));
|
||||
Assert.Equal("Value must be greater than or equal to 0.\r\nParameter name: minLength\r\n"+
|
||||
"Actual value was -1.",
|
||||
ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LengthRouteConstraint_SettingMaxLengthLessThanZero_Throws()
|
||||
{
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<ArgumentOutOfRangeException>(() => new LengthRouteConstraint(0, -1));
|
||||
Assert.Equal("Value must be greater than or equal to 0.\r\nParameter name: maxLength\r\n" +
|
||||
"Actual value was -1.",
|
||||
ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LengthRouteConstraint_MinGreaterThanMax_Throws()
|
||||
{
|
||||
// Arrange Act & Assert
|
||||
var ex = Assert.Throws<ArgumentOutOfRangeException>(() => new LengthRouteConstraint(3, 2));
|
||||
Assert.Equal("The value for argument 'minLength' should be less than or equal to the "+
|
||||
"value for the argument 'maxLength'.\r\nParameter name: minLength\r\nActual value was 3.",
|
||||
ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// 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.
|
||||
|
||||
#if NET45
|
||||
|
||||
using Microsoft.AspNet.Routing.Constraints;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public class LongRouteConstraintTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(42, true)]
|
||||
[InlineData(42L, true)]
|
||||
[InlineData("42", true)]
|
||||
[InlineData("9223372036854775807", true)]
|
||||
[InlineData(3.14, false)]
|
||||
[InlineData("43.567", false)]
|
||||
[InlineData("42a", false)]
|
||||
public void LongRouteConstraintTest(object parameterValue, bool expected)
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new LongRouteConstraint();
|
||||
|
||||
// Act
|
||||
var actual = ConstraintsTestHelper.TestConstraint(constraint, parameterValue);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
// 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.
|
||||
|
||||
#if NET45
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNet.Routing.Constraints;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public class MaxLengthRouteConstraintTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(3, "", true)]
|
||||
[InlineData(3, "12", true)]
|
||||
[InlineData(3, "123", true)]
|
||||
[InlineData(3, "1234", false)]
|
||||
public void MaxLengthRouteConstraint_ApplyConstraint(int min, string parameterValue, bool expected)
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new MaxLengthRouteConstraint(min);
|
||||
|
||||
// Act
|
||||
var actual = ConstraintsTestHelper.TestConstraint(constraint, parameterValue);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MaxLengthRouteConstraint_SettingMaxLengthLessThanZero_Throws()
|
||||
{
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<ArgumentOutOfRangeException>(()=> new MaxLengthRouteConstraint(-1));
|
||||
Assert.Equal("Value must be greater than or equal to 0.\r\nParameter name: maxLength\r\n" +
|
||||
"Actual value was -1.",
|
||||
ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// 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.
|
||||
|
||||
#if NET45
|
||||
|
||||
using Microsoft.AspNet.Routing.Constraints;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public class MaxRouteConstraintTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(3, 2, true)]
|
||||
[InlineData(3, 3, true)]
|
||||
[InlineData(3, 4, false)]
|
||||
public void MaxRouteConstraint_ApplyConstraint(long max, int parameterValue, bool expected)
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new MaxRouteConstraint(max);
|
||||
|
||||
// Act
|
||||
var actual = ConstraintsTestHelper.TestConstraint(constraint, parameterValue);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
// 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.
|
||||
|
||||
#if NET45
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNet.Routing.Constraints;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public class MinLengthRouteConstraintTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(3, "1234", true)]
|
||||
[InlineData(3, "123", true)]
|
||||
[InlineData(3, "12", false)]
|
||||
[InlineData(3, "", false)]
|
||||
public void MinLengthRouteConstraint_ApplyConstraint(int min, string parameterValue, bool expected)
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new MinLengthRouteConstraint(min);
|
||||
|
||||
// Act
|
||||
var actual = ConstraintsTestHelper.TestConstraint(constraint, parameterValue);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MinLengthRouteConstraint_SettingMinLengthLessThanZero_Throws()
|
||||
{
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<ArgumentOutOfRangeException>(() => new MinLengthRouteConstraint(-1));
|
||||
Assert.Equal("Value must be greater than or equal to 0.\r\nParameter name: minLength\r\n" +
|
||||
"Actual value was -1.",
|
||||
ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// 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.
|
||||
|
||||
#if NET45
|
||||
|
||||
using Microsoft.AspNet.Routing.Constraints;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public class MinRouteConstraintTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(3, 4, true)]
|
||||
[InlineData(3, 3, true)]
|
||||
[InlineData(3, 2, false)]
|
||||
public void MinRouteConstraint_ApplyConstraint(long min, int parameterValue, bool expected)
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new MinRouteConstraint(min);
|
||||
|
||||
// Act
|
||||
var actual = ConstraintsTestHelper.TestConstraint(constraint, parameterValue);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
// 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.
|
||||
|
||||
#if NET45
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNet.Routing.Constraints;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public class RangeRouteConstraintTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(long.MinValue, long.MaxValue, 2, true)]
|
||||
[InlineData(3, 5, 3, true)]
|
||||
[InlineData(3, 5, 4, true)]
|
||||
[InlineData(3, 5, 5, true)]
|
||||
[InlineData(3, 5, 6, false)]
|
||||
[InlineData(3, 5, 2, false)]
|
||||
[InlineData(3, 3, 2, false)]
|
||||
[InlineData(3, 3, 3, true)]
|
||||
public void RangeRouteConstraintTest_ValidValue_ApplyConstraint(long min, long max, int parameterValue, bool expected)
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new RangeRouteConstraint(min, max);
|
||||
|
||||
// Act
|
||||
var actual = ConstraintsTestHelper.TestConstraint(constraint, parameterValue);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RangeRouteConstraint_MinGreaterThanMax_Throws()
|
||||
{
|
||||
// Arrange Act & Assert
|
||||
var ex = Assert.Throws<ArgumentOutOfRangeException>(() => new RangeRouteConstraint(3, 2));
|
||||
Assert.Equal("The value for argument 'min' should be less than or equal to the value for the argument "+
|
||||
"'max'.\r\nParameter name: min\r\nActual value was 3.",
|
||||
ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -27,7 +27,7 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
bool shouldMatch)
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new RegexConstraint(constraintValue);
|
||||
var constraint = new RegexRouteConstraint(constraintValue);
|
||||
var values = new RouteValueDictionary(new {controller = routeValue});
|
||||
|
||||
// Assert
|
||||
|
|
@ -38,7 +38,7 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
public void RegexConstraint_TakesRegexAsInput_SimpleMatch()
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new RegexConstraint(new Regex("^abc$"));
|
||||
var constraint = new RegexRouteConstraint(new Regex("^abc$"));
|
||||
var values = new RouteValueDictionary(new { controller = "abc"});
|
||||
|
||||
// Assert
|
||||
|
|
@ -49,7 +49,7 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
public void RegexConstraintConstructedWithRegex_SimpleFailedMatch()
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new RegexConstraint(new Regex("^abc$"));
|
||||
var constraint = new RegexRouteConstraint(new Regex("^abc$"));
|
||||
var values = new RouteValueDictionary(new { controller = "Abc" });
|
||||
|
||||
// Assert
|
||||
|
|
@ -60,7 +60,7 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
public void RegexConstraintFailsIfKeyIsNotFoundInRouteValues()
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new RegexConstraint(new Regex("^abc$"));
|
||||
var constraint = new RegexRouteConstraint(new Regex("^abc$"));
|
||||
var values = new RouteValueDictionary(new { action = "abc" });
|
||||
|
||||
// Assert
|
||||
|
|
@ -71,7 +71,7 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
public void RegexConstraintIsCultureInsensitiveWhenConstructredWithString()
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new RegexConstraint("^([a-z]+)$");
|
||||
var constraint = new RegexRouteConstraint("^([a-z]+)$");
|
||||
var values = new RouteValueDictionary(new { controller = "\u0130" }); // Turkish upper-case dotted I
|
||||
|
||||
var currentThread = Thread.CurrentThread;
|
||||
|
|
@ -46,7 +46,7 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
|
||||
var constraint = constraintDictionary["controller"];
|
||||
|
||||
Assert.IsType<RegexConstraint>(constraint);
|
||||
Assert.IsType<RegexRouteConstraint>(constraint);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -15,15 +15,18 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
{
|
||||
public class DefaultInlineConstraintResolverTest
|
||||
{
|
||||
private IInlineConstraintResolver _constraintResolver;
|
||||
|
||||
public DefaultInlineConstraintResolverTest()
|
||||
{
|
||||
var routeOptions = new RouteOptions();
|
||||
_constraintResolver = GetInlineConstraintResolver(routeOptions);
|
||||
}
|
||||
[Fact]
|
||||
public void ResolveConstraint_IntConstraint_ResolvesCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
var routeOptions = new RouteOptions();
|
||||
var constraintResolver = GetInlineConstraintResolver(routeOptions);
|
||||
|
||||
// Act
|
||||
var constraint = constraintResolver.ResolveConstraint("int");
|
||||
// Arrange & Act
|
||||
var constraint = _constraintResolver.ResolveConstraint("int");
|
||||
|
||||
// Assert
|
||||
Assert.IsType<IntRouteConstraint>(constraint);
|
||||
|
|
@ -32,17 +35,190 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
[Fact]
|
||||
public void ResolveConstraint_IntConstraintWithArgument_Throws()
|
||||
{
|
||||
// Arrange
|
||||
var routeOptions = new RouteOptions();
|
||||
var constraintResolver = GetInlineConstraintResolver(routeOptions);
|
||||
|
||||
// Act & Assert
|
||||
// Arrange, Act & Assert
|
||||
var ex = Assert.Throws<InvalidOperationException>(
|
||||
() => constraintResolver.ResolveConstraint("int(5)"));
|
||||
() => _constraintResolver.ResolveConstraint("int(5)"));
|
||||
Assert.Equal("Could not find a constructor for constraint type 'IntRouteConstraint'"+
|
||||
" with the following number of parameters: 1.",
|
||||
ex.Message);
|
||||
}
|
||||
[Fact]
|
||||
public void ResolveConstraint_AlphaConstraint()
|
||||
{
|
||||
// Arrange & Act
|
||||
var constraint = _constraintResolver.ResolveConstraint("alpha");
|
||||
|
||||
// Assert
|
||||
Assert.IsType<AlphaRouteConstraint>(constraint);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveConstraint_BoolConstraint()
|
||||
{
|
||||
// Arrange & Act
|
||||
var constraint = _constraintResolver.ResolveConstraint("bool");
|
||||
|
||||
// Assert
|
||||
Assert.IsType<BoolRouteConstraint>(constraint);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveConstraint_CompositeConstraintIsNotRegistered()
|
||||
{
|
||||
// Arrange, Act & Assert
|
||||
Assert.Null(_constraintResolver.ResolveConstraint("composite"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveConstraint_DateTimeConstraint()
|
||||
{
|
||||
// Arrange & Act
|
||||
var constraint = _constraintResolver.ResolveConstraint("datetime");
|
||||
|
||||
// Assert
|
||||
Assert.IsType<DateTimeRouteConstraint>(constraint);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveConstraint_DecimalConstraint()
|
||||
{
|
||||
// Arrange & Act
|
||||
var constraint = _constraintResolver.ResolveConstraint("decimal");
|
||||
|
||||
// Assert
|
||||
Assert.IsType<DecimalRouteConstraint>(constraint);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveConstraint_DoubleConstraint()
|
||||
{
|
||||
// Arrange & Act
|
||||
var constraint = _constraintResolver.ResolveConstraint("double");
|
||||
|
||||
// Assert
|
||||
Assert.IsType<DoubleRouteConstraint>(constraint);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveConstraint_FloatConstraint()
|
||||
{
|
||||
// Arrange & Act
|
||||
var constraint = _constraintResolver.ResolveConstraint("float");
|
||||
|
||||
// Assert
|
||||
Assert.IsType<FloatRouteConstraint>(constraint);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveConstraint_GuidConstraint()
|
||||
{
|
||||
// Arrange & Act
|
||||
var constraint = _constraintResolver.ResolveConstraint("guid");
|
||||
|
||||
// Assert
|
||||
Assert.IsType<GuidRouteConstraint>(constraint);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveConstraint_IntConstraint()
|
||||
{
|
||||
// Arrange & Act
|
||||
var constraint = _constraintResolver.ResolveConstraint("int");
|
||||
|
||||
// Assert
|
||||
Assert.IsType<IntRouteConstraint>(constraint);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveConstraint_LengthConstraint()
|
||||
{
|
||||
// Arrange & Act
|
||||
var constraint = _constraintResolver.ResolveConstraint("length(5)");
|
||||
|
||||
// Assert
|
||||
Assert.IsType<LengthRouteConstraint>(constraint);
|
||||
Assert.Equal(5, ((LengthRouteConstraint)constraint).MinLength);
|
||||
Assert.Equal(5, ((LengthRouteConstraint)constraint).MaxLength);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveConstraint_LengthRangeConstraint()
|
||||
{
|
||||
// Arrange & Act
|
||||
var constraint = _constraintResolver.ResolveConstraint("length(5, 10)");
|
||||
|
||||
// Assert
|
||||
var lengthConstraint = Assert.IsType<LengthRouteConstraint>(constraint);
|
||||
Assert.Equal(5, lengthConstraint.MinLength);
|
||||
Assert.Equal(10, lengthConstraint.MaxLength);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveConstraint_LongRangeConstraint()
|
||||
{
|
||||
// Arrange & Act
|
||||
var constraint = _constraintResolver.ResolveConstraint("long");
|
||||
|
||||
// Assert
|
||||
Assert.IsType<LongRouteConstraint>(constraint);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveConstraint_MaxConstraint()
|
||||
{
|
||||
// Arrange & Act
|
||||
var constraint = _constraintResolver.ResolveConstraint("max(10)");
|
||||
|
||||
// Assert
|
||||
Assert.IsType<MaxRouteConstraint>(constraint);
|
||||
Assert.Equal(10, ((MaxRouteConstraint)constraint).Max);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveConstraint_MaxLengthConstraint()
|
||||
{
|
||||
// Arrange & Act
|
||||
var constraint = _constraintResolver.ResolveConstraint("maxlength(10)");
|
||||
|
||||
// Assert
|
||||
Assert.IsType<MaxLengthRouteConstraint>(constraint);
|
||||
Assert.Equal(10, ((MaxLengthRouteConstraint)constraint).MaxLength);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveConstraint_MinConstraint()
|
||||
{
|
||||
// Arrange & Act
|
||||
var constraint = _constraintResolver.ResolveConstraint("min(3)");
|
||||
|
||||
// Assert
|
||||
Assert.IsType<MinRouteConstraint>(constraint);
|
||||
Assert.Equal(3, ((MinRouteConstraint)constraint).Min);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveConstraint_MinLengthConstraint()
|
||||
{
|
||||
// Arrange & Act
|
||||
var constraint = _constraintResolver.ResolveConstraint("minlength(3)");
|
||||
|
||||
// Assert
|
||||
Assert.IsType<MinLengthRouteConstraint>(constraint);
|
||||
Assert.Equal(3, ((MinLengthRouteConstraint)constraint).MinLength);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveConstraint_RangeConstraint()
|
||||
{
|
||||
// Arrange & Act
|
||||
var constraint = _constraintResolver.ResolveConstraint("range(5, 10)");
|
||||
|
||||
// Assert
|
||||
Assert.IsType<RangeRouteConstraint>(constraint);
|
||||
var rangeConstraint = (RangeRouteConstraint)constraint;
|
||||
Assert.Equal(5, rangeConstraint.Min);
|
||||
Assert.Equal(10, rangeConstraint.Max);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveConstraint_SupportsCustomConstraints()
|
||||
|
|
@ -74,6 +250,32 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveConstraint_AmbiguousConstructors_Throws()
|
||||
{
|
||||
// Arrange
|
||||
var routeOptions = new RouteOptions();
|
||||
routeOptions.ConstraintMap.Add("custom", typeof(MultiConstructorRouteConstraint));
|
||||
var resolver = GetInlineConstraintResolver(routeOptions);
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => resolver.ResolveConstraint("custom(5,6)"));
|
||||
Assert.Equal("The constructor to use for activating the constraint type 'MultiConstructorRouteConstraint' is ambiguous." +
|
||||
" Multiple constructors were found with the following number of parameters: 2.",
|
||||
ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveConstraint_NoMatchingConstructor_Throws()
|
||||
{
|
||||
// Arrange
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => _constraintResolver.ResolveConstraint("int(5,6)"));
|
||||
Assert.Equal("Could not find a constructor for constraint type 'IntRouteConstraint'" +
|
||||
" with the following number of parameters: 2.",
|
||||
ex.Message);
|
||||
}
|
||||
|
||||
private IInlineConstraintResolver GetInlineConstraintResolver(RouteOptions routeOptions)
|
||||
{
|
||||
var optionsAccessor = new Mock<IOptionsAccessor<RouteOptions>>();
|
||||
|
|
@ -84,6 +286,26 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
return new DefaultInlineConstraintResolver(serviceProvider.Object, optionsAccessor.Object);
|
||||
}
|
||||
|
||||
private class MultiConstructorRouteConstraint : IRouteConstraint
|
||||
{
|
||||
public MultiConstructorRouteConstraint(string pattern, int intArg)
|
||||
{
|
||||
}
|
||||
|
||||
public MultiConstructorRouteConstraint(int intArg, string pattern)
|
||||
{
|
||||
}
|
||||
|
||||
public bool Match(HttpContext httpContext,
|
||||
IRouter route,
|
||||
string routeKey,
|
||||
IDictionary<string, object> values,
|
||||
RouteDirection routeDirection)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class CustomRouteConstraint : IRouteConstraint
|
||||
{
|
||||
public CustomRouteConstraint(string pattern)
|
||||
|
|
|
|||
|
|
@ -176,6 +176,18 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
Assert.Equal(@"\w,\w", ((TestRouteConstraint)templatePart.InlineConstraint).Pattern);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParseRouteParameter_ConstraintWithEqualsFollowedByQuestionMark_PatternIsParsedCorrectly()
|
||||
{
|
||||
// Arrange & Act
|
||||
var templatePart = ParseParameter(@"param:int=?");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("param", templatePart.Name);
|
||||
var constraint = Assert.IsType<IntRouteConstraint>(templatePart.InlineConstraint);
|
||||
Assert.Equal("", templatePart.DefaultValue);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(",")]
|
||||
[InlineData("(")]
|
||||
|
|
@ -270,15 +282,15 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
|
||||
private TemplatePart ParseParameter(string routeParameter)
|
||||
{
|
||||
var constraintResolver = GetConstraintResolver();
|
||||
var templatePart = InlineRouteParameterParser.ParseRouteParameter(routeParameter, constraintResolver);
|
||||
var _constraintResolver = GetConstraintResolver();
|
||||
var templatePart = InlineRouteParameterParser.ParseRouteParameter(routeParameter, _constraintResolver);
|
||||
return templatePart;
|
||||
}
|
||||
|
||||
private static Template.Template ParseRouteTemplate(string template)
|
||||
{
|
||||
var constraintResolver = GetConstraintResolver();
|
||||
return TemplateParser.Parse(template, constraintResolver);
|
||||
var _constraintResolver = GetConstraintResolver();
|
||||
return TemplateParser.Parse(template, _constraintResolver);
|
||||
}
|
||||
|
||||
private static IInlineConstraintResolver GetConstraintResolver()
|
||||
|
|
|
|||
|
|
@ -22,16 +22,35 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="ConstraintMatcherTests.cs" />
|
||||
<Compile Include="ConstraintsBuilderTests.cs" />
|
||||
<Compile Include="Constraints\ConstraintsTestHelper.cs" />
|
||||
<Compile Include="Constraints\BoolRouteConstraintTests.cs" />
|
||||
<Compile Include="Constraints\DateTimeRouteConstraintTests.cs" />
|
||||
<Compile Include="Constraints\DecimalRouteConstraintTests.cs" />
|
||||
<Compile Include="Constraints\DoubleRouteConstraintTests.cs" />
|
||||
<Compile Include="Constraints\FloatRouteConstraintTests.cs" />
|
||||
<Compile Include="Constraints\GuidRouteConstraintTests.cs" />
|
||||
<Compile Include="Constraints\LengthRouteConstraintTests.cs" />
|
||||
<Compile Include="Constraints\CompositeRouteConstraintTests.cs" />
|
||||
<Compile Include="Constraints\MaxLengthRouteConstraintTests.cs" />
|
||||
<Compile Include="Constraints\MinLengthRouteConstraintTests.cs" />
|
||||
<Compile Include="Constraints\MaxRouteConstraintTests.cs" />
|
||||
<Compile Include="Constraints\LongRouteConstraintTests.cs" />
|
||||
<Compile Include="Constraints\RangeRouteConstraintTests.cs" />
|
||||
<Compile Include="Constraints\MinRouteConstraintTests.cs" />
|
||||
<Compile Include="Constraints\AlphaRouteConstraintTests.cs" />
|
||||
<Compile Include="Constraints\RegexConstraintTests.cs" />
|
||||
<Compile Include="Constraints\IntRouteConstraintsTests.cs" />
|
||||
<Compile Include="DefaultInlineConstraintResolverTest.cs" />
|
||||
<Compile Include="RegexConstraintTests.cs" />
|
||||
<Compile Include="RouteCollectionTest.cs" />
|
||||
<Compile Include="InlineRouteParameterParserTests.cs" />
|
||||
<Compile Include="RouteConstraintsTests.cs" />
|
||||
<Compile Include="DefaultValueTests.cs" />
|
||||
<Compile Include="RouteOptionsTests.cs" />
|
||||
<Compile Include="RouteValueDictionaryTests.cs" />
|
||||
<Compile Include="TemplateParserDefaultValuesTests.cs" />
|
||||
<Compile Include="Template\TemplateBinderTests.cs" />
|
||||
<Compile Include="Template\TemplateMatcherTests.cs" />
|
||||
<Compile Include="Template\TemplateParserTests.cs" />
|
||||
<Compile Include="Template\TemplateRouteTests.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
@ -423,7 +423,7 @@ namespace Microsoft.AspNet.Routing.Template.Tests
|
|||
|
||||
// Assert
|
||||
Assert.Equal(2, constraints.Count);
|
||||
Assert.IsType<RegexConstraint>(constraints["controller"]);
|
||||
Assert.IsType<RegexRouteConstraint>(constraints["controller"]);
|
||||
Assert.Equal(mockConstraint, constraints["action"]);
|
||||
}
|
||||
|
||||
|
|
@ -444,7 +444,7 @@ namespace Microsoft.AspNet.Routing.Template.Tests
|
|||
Assert.Equal(1, constraints.Count);
|
||||
var constraint = (CompositeRouteConstraint)constraints["id"];
|
||||
Assert.IsType<CompositeRouteConstraint>(constraint);
|
||||
Assert.IsType<RegexConstraint>(constraint.Constraints.ElementAt(0));
|
||||
Assert.IsType<RegexRouteConstraint>(constraint.Constraints.ElementAt(0));
|
||||
Assert.IsType<IntRouteConstraint>(constraint.Constraints.ElementAt(1));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,117 @@
|
|||
// 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.
|
||||
|
||||
#if NET45
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Routing.Constraints;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.DependencyInjection.Fallback;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public class TemplateParserDefaultValuesTests
|
||||
{
|
||||
private static IInlineConstraintResolver _inlineConstraintResolver = GetInlineConstraintResolver();
|
||||
|
||||
[Fact]
|
||||
public void InlineDefaultValueSpecified_InlineValueIsUsed()
|
||||
{
|
||||
// Arrange & Act
|
||||
var routeBuilder = CreateRouteBuilder();
|
||||
|
||||
// Act
|
||||
routeBuilder.MapRoute("mockName",
|
||||
"{controller}/{action}/{id:int=12}",
|
||||
defaults: null,
|
||||
constraints: null);
|
||||
|
||||
// Assert
|
||||
var defaults = ((Template.TemplateRoute)routeBuilder.Routes[0]).Defaults;
|
||||
Assert.Equal("12", defaults["id"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExplicitDefaultValueSpecified_WithInlineDefaultValue_Throws()
|
||||
{
|
||||
// Arrange
|
||||
var routeBuilder = CreateRouteBuilder();
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<InvalidOperationException>(
|
||||
() => routeBuilder.MapRoute("mockName",
|
||||
"{controller}/{action}/{id:int=12}",
|
||||
defaults: new { id = 13 },
|
||||
constraints: null));
|
||||
|
||||
var message = "The route parameter 'id' has both an inline default value and an explicit default" +
|
||||
" value specified. A route parameter cannot contain an inline default value when" +
|
||||
" a default value is specified explicitly. Consider removing one of them.";
|
||||
Assert.Equal(message, ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyDefaultValue_WithOptionalParameter_Throws()
|
||||
{
|
||||
// Arrange
|
||||
var routeBuilder = CreateRouteBuilder();
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<ArgumentException>(
|
||||
() => routeBuilder.MapRoute("mockName",
|
||||
"{controller}/{action}/{id:int=?}",
|
||||
defaults: new { id = 13 },
|
||||
constraints: null));
|
||||
|
||||
var message = "An optional parameter cannot have default value.\r\nParameter name: routeTemplate";
|
||||
Assert.Equal(message, ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NonEmptyDefaultValue_WithOptionalParameter_Throws()
|
||||
{
|
||||
// Arrange
|
||||
var routeBuilder = CreateRouteBuilder();
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<ArgumentException>(
|
||||
() => routeBuilder.MapRoute("mockName",
|
||||
"{controller}/{action}/{id:int=12?}",
|
||||
defaults: new { id = 13 },
|
||||
constraints: null));
|
||||
|
||||
var message = "An optional parameter cannot have default value.\r\nParameter name: routeTemplate";
|
||||
Assert.Equal(message, ex.Message);
|
||||
}
|
||||
|
||||
private static IRouteBuilder CreateRouteBuilder()
|
||||
{
|
||||
var routeBuilder = new RouteBuilder();
|
||||
|
||||
routeBuilder.DefaultHandler = new Mock<IRouter>().Object;
|
||||
|
||||
var serviceProviderMock = new Mock<IServiceProvider>();
|
||||
serviceProviderMock.Setup(o => o.GetService(typeof(IInlineConstraintResolver)))
|
||||
.Returns(_inlineConstraintResolver);
|
||||
routeBuilder.ServiceProvider = serviceProviderMock.Object;
|
||||
|
||||
return routeBuilder;
|
||||
}
|
||||
|
||||
private static IInlineConstraintResolver GetInlineConstraintResolver()
|
||||
{
|
||||
var services = new ServiceCollection { OptionsServices.GetDefaultServices() };
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
var accessor = serviceProvider.GetService<IOptionsAccessor<RouteOptions>>();
|
||||
return new DefaultInlineConstraintResolver(serviceProvider, accessor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue