[Fixes #4991] Misleading MissingMethodException message for incorrect routes
This commit is contained in:
parent
d20cb17c52
commit
714c3d6659
|
|
@ -69,12 +69,25 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
|
|
||||||
if (!typeof(IRouteConstraint).GetTypeInfo().IsAssignableFrom(constraintType.GetTypeInfo()))
|
if (!typeof(IRouteConstraint).GetTypeInfo().IsAssignableFrom(constraintType.GetTypeInfo()))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(
|
throw new RouteCreationException(
|
||||||
Resources.FormatDefaultInlineConstraintResolver_TypeNotConstraint(
|
Resources.FormatDefaultInlineConstraintResolver_TypeNotConstraint(
|
||||||
constraintType, constraintKey, typeof(IRouteConstraint).Name));
|
constraintType, constraintKey, typeof(IRouteConstraint).Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
return CreateConstraint(constraintType, argumentString);
|
try
|
||||||
|
{
|
||||||
|
return CreateConstraint(constraintType, argumentString);
|
||||||
|
}
|
||||||
|
catch (RouteCreationException)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
throw new RouteCreationException(
|
||||||
|
$"An error occurred while trying to create an instance of route constraint '{constraintType.FullName}'.",
|
||||||
|
exception);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IRouteConstraint CreateConstraint(Type constraintType, string argumentString)
|
private static IRouteConstraint CreateConstraint(Type constraintType, string argumentString)
|
||||||
|
|
@ -107,7 +120,7 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
|
|
||||||
if (constructorMatches == 0)
|
if (constructorMatches == 0)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(
|
throw new RouteCreationException(
|
||||||
Resources.FormatDefaultInlineConstraintResolver_CouldNotFindCtor(
|
Resources.FormatDefaultInlineConstraintResolver_CouldNotFindCtor(
|
||||||
constraintTypeInfo.Name, arguments.Length));
|
constraintTypeInfo.Name, arguments.Length));
|
||||||
}
|
}
|
||||||
|
|
@ -118,7 +131,7 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(
|
throw new RouteCreationException(
|
||||||
Resources.FormatDefaultInlineConstraintResolver_AmbiguousCtors(
|
Resources.FormatDefaultInlineConstraintResolver_AmbiguousCtors(
|
||||||
constraintTypeInfo.Name, arguments.Length));
|
constraintTypeInfo.Name, arguments.Length));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Builder
|
||||||
/// <param name="name">The name of the route.</param>
|
/// <param name="name">The name of the route.</param>
|
||||||
/// <param name="template">The URL pattern of the route.</param>
|
/// <param name="template">The URL pattern of the route.</param>
|
||||||
/// <param name="defaults">
|
/// <param name="defaults">
|
||||||
/// An object that contains default values for route parameters. The object's properties represent the names
|
/// An object that contains default values for route parameters. The object's properties represent the names
|
||||||
/// and values of the default values.
|
/// and values of the default values.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||||
|
|
@ -104,7 +104,7 @@ namespace Microsoft.AspNetCore.Builder
|
||||||
{
|
{
|
||||||
if (routeBuilder.DefaultHandler == null)
|
if (routeBuilder.DefaultHandler == null)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(Resources.DefaultHandler_MustBeSet);
|
throw new RouteCreationException(Resources.DefaultHandler_MustBeSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
var inlineConstraintResolver = routeBuilder
|
var inlineConstraintResolver = routeBuilder
|
||||||
|
|
|
||||||
|
|
@ -442,6 +442,22 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("UnableToFindServices"), p0, p1, p2);
|
return string.Format(CultureInfo.CurrentCulture, GetString("UnableToFindServices"), p0, p1, p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An error occurred while creating the route with name '{0}' and template '{1}'.
|
||||||
|
/// </summary>
|
||||||
|
internal static string TemplateRoute_Exception
|
||||||
|
{
|
||||||
|
get { return GetString("TemplateRoute_Exception"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An error occurred while creating the route with name '{0}' and template '{1}'.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatTemplateRoute_Exception(object p0, object p1)
|
||||||
|
{
|
||||||
|
return string.Format(CultureInfo.CurrentCulture, GetString("TemplateRoute_Exception"), p0, p1);
|
||||||
|
}
|
||||||
|
|
||||||
private static string GetString(string name, params string[] formatterNames)
|
private static string GetString(string name, params string[] formatterNames)
|
||||||
{
|
{
|
||||||
var value = _resourceManager.GetString(name);
|
var value = _resourceManager.GetString(name);
|
||||||
|
|
|
||||||
|
|
@ -198,4 +198,7 @@
|
||||||
<data name="UnableToFindServices" xml:space="preserve">
|
<data name="UnableToFindServices" xml:space="preserve">
|
||||||
<value>Unable to find the required services. Please add all the required services by calling '{0}.{1}' inside the call to '{2}' in the application startup code.</value>
|
<value>Unable to find the required services. Please add all the required services by calling '{0}.{1}' inside the call to '{2}' in the application startup code.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TemplateRoute_Exception" xml:space="preserve">
|
||||||
|
<value>An error occurred while creating the route with name '{0}' and template '{1}'.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -46,12 +46,19 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
ConstraintResolver = constraintResolver;
|
ConstraintResolver = constraintResolver;
|
||||||
DataTokens = dataTokens ?? new RouteValueDictionary();
|
DataTokens = dataTokens ?? new RouteValueDictionary();
|
||||||
|
|
||||||
// Data we parse from the template will be used to fill in the rest of the constraints or
|
try
|
||||||
// defaults. The parser will throw for invalid routes.
|
{
|
||||||
ParsedTemplate = TemplateParser.Parse(template);
|
// Data we parse from the template will be used to fill in the rest of the constraints or
|
||||||
|
// defaults. The parser will throw for invalid routes.
|
||||||
|
ParsedTemplate = TemplateParser.Parse(template);
|
||||||
|
|
||||||
Constraints = GetConstraints(constraintResolver, ParsedTemplate, constraints);
|
Constraints = GetConstraints(constraintResolver, ParsedTemplate, constraints);
|
||||||
Defaults = GetDefaults(ParsedTemplate, defaults);
|
Defaults = GetDefaults(ParsedTemplate, defaults);
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
throw new RouteCreationException(Resources.FormatTemplateRoute_Exception(name, template), exception);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IDictionary<string, IRouteConstraint> Constraints { get; protected set; }
|
public virtual IDictionary<string, IRouteConstraint> Constraints { get; protected set; }
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
var regexPattern = value as string;
|
var regexPattern = value as string;
|
||||||
if (regexPattern == null)
|
if (regexPattern == null)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(
|
throw new RouteCreationException(
|
||||||
Resources.FormatRouteConstraintBuilder_ValidationMustBeStringOrCustomConstraint(
|
Resources.FormatRouteConstraintBuilder_ValidationMustBeStringOrCustomConstraint(
|
||||||
key,
|
key,
|
||||||
value,
|
value,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Routing
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The exception that is thrown for invalid routes or constraints.
|
||||||
|
/// </summary>
|
||||||
|
public class RouteCreationException : Exception
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="RouteCreationException"/> class with a specified error message.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message that describes the error.</param>
|
||||||
|
public RouteCreationException(string message)
|
||||||
|
: base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="RouteCreationException"/> class with a specified error message
|
||||||
|
/// and a reference to the inner exception that is the cause of this exception.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||||
|
/// <param name="innerException">The exception that is the cause of the current exception.</param>
|
||||||
|
public RouteCreationException(string message, Exception innerException)
|
||||||
|
: base(message, innerException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -46,8 +46,9 @@ namespace Microsoft.AspNetCore.Routing.Tests
|
||||||
public void ResolveConstraint_IntConstraintWithArgument_Throws()
|
public void ResolveConstraint_IntConstraintWithArgument_Throws()
|
||||||
{
|
{
|
||||||
// Arrange, Act & Assert
|
// Arrange, Act & Assert
|
||||||
var ex = Assert.Throws<InvalidOperationException>(
|
var ex = Assert.Throws<RouteCreationException>(
|
||||||
() => _constraintResolver.ResolveConstraint("int(5)"));
|
() => _constraintResolver.ResolveConstraint("int(5)"));
|
||||||
|
|
||||||
Assert.Equal("Could not find a constructor for constraint type 'IntRouteConstraint'" +
|
Assert.Equal("Could not find a constructor for constraint type 'IntRouteConstraint'" +
|
||||||
" with the following number of parameters: 1.",
|
" with the following number of parameters: 1.",
|
||||||
ex.Message);
|
ex.Message);
|
||||||
|
|
@ -276,7 +277,7 @@ namespace Microsoft.AspNetCore.Routing.Tests
|
||||||
var resolver = GetInlineConstraintResolver(routeOptions);
|
var resolver = GetInlineConstraintResolver(routeOptions);
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
var ex = Assert.Throws<InvalidOperationException>(() => resolver.ResolveConstraint("custom"));
|
var ex = Assert.Throws<RouteCreationException>(() => resolver.ResolveConstraint("custom"));
|
||||||
Assert.Equal("The constraint type 'System.String' which is mapped to constraint key 'custom'" +
|
Assert.Equal("The constraint type 'System.String' which is mapped to constraint key 'custom'" +
|
||||||
" must implement the 'IRouteConstraint' interface.",
|
" must implement the 'IRouteConstraint' interface.",
|
||||||
ex.Message);
|
ex.Message);
|
||||||
|
|
@ -291,7 +292,7 @@ namespace Microsoft.AspNetCore.Routing.Tests
|
||||||
var resolver = GetInlineConstraintResolver(routeOptions);
|
var resolver = GetInlineConstraintResolver(routeOptions);
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
var ex = Assert.Throws<InvalidOperationException>(() => resolver.ResolveConstraint("custom(5,6)"));
|
var ex = Assert.Throws<RouteCreationException>(() => resolver.ResolveConstraint("custom(5,6)"));
|
||||||
Assert.Equal("The constructor to use for activating the constraint type 'MultiConstructorRouteConstraint' is ambiguous." +
|
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.",
|
" Multiple constructors were found with the following number of parameters: 2.",
|
||||||
ex.Message);
|
ex.Message);
|
||||||
|
|
@ -317,7 +318,7 @@ namespace Microsoft.AspNetCore.Routing.Tests
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
var ex = Assert.Throws<InvalidOperationException>(() => _constraintResolver.ResolveConstraint("int(5,6)"));
|
var ex = Assert.Throws<RouteCreationException>(() => _constraintResolver.ResolveConstraint("int(5,6)"));
|
||||||
Assert.Equal("Could not find a constructor for constraint type 'IntRouteConstraint'" +
|
Assert.Equal("Could not find a constructor for constraint type 'IntRouteConstraint'" +
|
||||||
" with the following number of parameters: 2.",
|
" with the following number of parameters: 2.",
|
||||||
ex.Message);
|
ex.Message);
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
var builder = CreateBuilder("{controller}/{action}");
|
var builder = CreateBuilder("{controller}/{action}");
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
ExceptionAssert.Throws<InvalidOperationException>(
|
ExceptionAssert.Throws<RouteCreationException>(
|
||||||
() => builder.AddConstraint("controller", 5),
|
() => builder.AddConstraint("controller", 5),
|
||||||
"The constraint entry 'controller' - '5' on the route " +
|
"The constraint entry 'controller' - '5' on the route " +
|
||||||
"'{controller}/{action}' must have a string value or be of a type which implements '" +
|
"'{controller}/{action}' must have a string value or be of a type which implements '" +
|
||||||
|
|
@ -117,7 +117,7 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
[Fact]
|
[Fact]
|
||||||
public void AddResolvedConstraint_SetOptionalParameter_AfterAddingTheParameter()
|
public void AddResolvedConstraint_SetOptionalParameter_AfterAddingTheParameter()
|
||||||
{
|
{
|
||||||
var builder = CreateBuilder("{controller}/{action}/{id}");
|
var builder = CreateBuilder("{controller}/{action}/{id}");
|
||||||
builder.AddResolvedConstraint("id", "int");
|
builder.AddResolvedConstraint("id", "int");
|
||||||
builder.SetOptional("id");
|
builder.SetOptional("id");
|
||||||
|
|
||||||
|
|
@ -140,7 +140,7 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
Assert.Equal(1, result.Count);
|
Assert.Equal(1, result.Count);
|
||||||
Assert.Equal("name", result.First().Key);
|
Assert.Equal("name", result.First().Key);
|
||||||
Assert.IsType<OptionalRouteConstraint>(Assert.Single(result).Value);
|
Assert.IsType<OptionalRouteConstraint>(Assert.Single(result).Value);
|
||||||
var optionalConstraint = (OptionalRouteConstraint)result.First().Value;
|
var optionalConstraint = (OptionalRouteConstraint)result.First().Value;
|
||||||
var compositeConstraint = Assert.IsType<CompositeRouteConstraint>(optionalConstraint.InnerConstraint); ;
|
var compositeConstraint = Assert.IsType<CompositeRouteConstraint>(optionalConstraint.InnerConstraint); ;
|
||||||
Assert.Equal(compositeConstraint.Constraints.Count(), 2);
|
Assert.Equal(compositeConstraint.Constraints.Count(), 2);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,11 +30,8 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
// Arrange
|
// Arrange
|
||||||
var template = @"{controller}/{action}/ {p1:regex(abc} ";
|
var template = @"{controller}/{action}/ {p1:regex(abc} ";
|
||||||
var mockTarget = new Mock<IRouter>(MockBehavior.Strict);
|
var mockTarget = new Mock<IRouter>(MockBehavior.Strict);
|
||||||
var expected = "The constraint entry 'p1' - 'regex(abc' on the route " +
|
|
||||||
"'{controller}/{action}/ {p1:regex(abc} ' could not be resolved by the constraint resolver of type " +
|
|
||||||
"'IInlineConstraintResolverProxy'.";
|
|
||||||
|
|
||||||
var exception = Assert.Throws<InvalidOperationException>(
|
var exception = Assert.Throws<RouteCreationException>(
|
||||||
() => new Route(
|
() => new Route(
|
||||||
mockTarget.Object,
|
mockTarget.Object,
|
||||||
template,
|
template,
|
||||||
|
|
@ -43,7 +40,15 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
dataTokens: null,
|
dataTokens: null,
|
||||||
inlineConstraintResolver: _inlineConstraintResolver));
|
inlineConstraintResolver: _inlineConstraintResolver));
|
||||||
|
|
||||||
|
var expected = "An error occurred while creating the route with name '' and template" +
|
||||||
|
$" '{template}'.";
|
||||||
Assert.Equal(expected, exception.Message);
|
Assert.Equal(expected, exception.Message);
|
||||||
|
|
||||||
|
Assert.NotNull(exception.InnerException);
|
||||||
|
expected = "The constraint entry 'p1' - 'regex(abc' on the route " +
|
||||||
|
"'{controller}/{action}/ {p1:regex(abc} ' could not be resolved by the constraint resolver of type " +
|
||||||
|
"'IInlineConstraintResolverProxy'.";
|
||||||
|
Assert.Equal(expected, exception.InnerException.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -1460,14 +1465,21 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
var routeBuilder = CreateRouteBuilder();
|
var routeBuilder = CreateRouteBuilder();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
ExceptionAssert.Throws<InvalidOperationException>(
|
var expectedMessage = "An error occurred while creating the route with name 'mockName' and template" +
|
||||||
|
" '{controller}/{action}'.";
|
||||||
|
|
||||||
|
var exception = ExceptionAssert.Throws<RouteCreationException>(
|
||||||
() => routeBuilder.MapRoute("mockName",
|
() => routeBuilder.MapRoute("mockName",
|
||||||
"{controller}/{action}",
|
"{controller}/{action}",
|
||||||
defaults: null,
|
defaults: null,
|
||||||
constraints: new { controller = "a.*", action = 17 }),
|
constraints: new { controller = "a.*", action = 17 }),
|
||||||
"The constraint entry 'action' - '17' on the route '{controller}/{action}' " +
|
expectedMessage);
|
||||||
|
|
||||||
|
expectedMessage = "The constraint entry 'action' - '17' on the route '{controller}/{action}' " +
|
||||||
"must have a string value or be of a type which implements '" +
|
"must have a string value or be of a type which implements '" +
|
||||||
typeof(IRouteConstraint) + "'.");
|
typeof(IRouteConstraint) + "'.";
|
||||||
|
Assert.NotNull(exception.InnerException);
|
||||||
|
Assert.Equal(expectedMessage, exception.InnerException.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
|
|
@ -58,46 +58,54 @@ namespace Microsoft.AspNetCore.Routing.Tests
|
||||||
var routeBuilder = CreateRouteBuilder();
|
var routeBuilder = CreateRouteBuilder();
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
var ex = Assert.Throws<InvalidOperationException>(
|
var ex = Assert.Throws<RouteCreationException>(
|
||||||
() => routeBuilder.MapRoute("mockName",
|
() => routeBuilder.MapRoute("mockName",
|
||||||
"{controller}/{action}/{id:int=12}",
|
"{controller}/{action}/{id:int=12}",
|
||||||
defaults: new { id = 13 },
|
defaults: new { id = 13 },
|
||||||
constraints: null));
|
constraints: null));
|
||||||
|
|
||||||
var message = "The route parameter 'id' has both an inline default value and an explicit default" +
|
var message = "An error occurred while creating the route with name 'mockName' and template" +
|
||||||
" value specified. A route parameter cannot contain an inline default value when" +
|
" '{controller}/{action}/{id:int=12}'.";
|
||||||
" a default value is specified explicitly. Consider removing one of them.";
|
|
||||||
Assert.Equal(message, ex.Message);
|
Assert.Equal(message, ex.Message);
|
||||||
|
|
||||||
|
Assert.NotNull(ex.InnerException);
|
||||||
|
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.InnerException.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void EmptyDefaultValue_WithOptionalParameter_Throws()
|
public void EmptyDefaultValue_WithOptionalParameter_Throws()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var message = "An optional parameter cannot have default value." + Environment.NewLine +
|
|
||||||
"Parameter name: routeTemplate";
|
|
||||||
var routeBuilder = CreateRouteBuilder();
|
var routeBuilder = CreateRouteBuilder();
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
var ex = Assert.Throws<ArgumentException>(
|
var ex = Assert.Throws<RouteCreationException>(
|
||||||
() => routeBuilder.MapRoute("mockName",
|
() => routeBuilder.MapRoute("mockName",
|
||||||
"{controller}/{action}/{id:int=?}",
|
"{controller}/{action}/{id:int=?}",
|
||||||
defaults: new { id = 13 },
|
defaults: new { id = 13 },
|
||||||
constraints: null));
|
constraints: null));
|
||||||
|
|
||||||
|
var message = "An error occurred while creating the route with name 'mockName' and template" +
|
||||||
|
" '{controller}/{action}/{id:int=?}'.";
|
||||||
Assert.Equal(message, ex.Message);
|
Assert.Equal(message, ex.Message);
|
||||||
|
|
||||||
|
Assert.NotNull(ex.InnerException);
|
||||||
|
message = "An optional parameter cannot have default value." + Environment.NewLine +
|
||||||
|
"Parameter name: routeTemplate";
|
||||||
|
Assert.Equal(message, ex.InnerException.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void NonEmptyDefaultValue_WithOptionalParameter_Throws()
|
public void NonEmptyDefaultValue_WithOptionalParameter_Throws()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var message = "An optional parameter cannot have default value." + Environment.NewLine +
|
|
||||||
"Parameter name: routeTemplate";
|
|
||||||
var routeBuilder = CreateRouteBuilder();
|
var routeBuilder = CreateRouteBuilder();
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
var ex = Assert.Throws<ArgumentException>(() =>
|
var ex = Assert.Throws<RouteCreationException>(() =>
|
||||||
{
|
{
|
||||||
routeBuilder.MapRoute(
|
routeBuilder.MapRoute(
|
||||||
"mockName",
|
"mockName",
|
||||||
|
|
@ -106,7 +114,14 @@ namespace Microsoft.AspNetCore.Routing.Tests
|
||||||
constraints: null);
|
constraints: null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var message = "An error occurred while creating the route with name 'mockName' and template" +
|
||||||
|
" '{controller}/{action}/{id:int=12?}'.";
|
||||||
Assert.Equal(message, ex.Message);
|
Assert.Equal(message, ex.Message);
|
||||||
|
|
||||||
|
Assert.NotNull(ex.InnerException);
|
||||||
|
message = "An optional parameter cannot have default value." + Environment.NewLine +
|
||||||
|
"Parameter name: routeTemplate";
|
||||||
|
Assert.Equal(message, ex.InnerException.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IRouteBuilder CreateRouteBuilder()
|
private static IRouteBuilder CreateRouteBuilder()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue