update due to breaking changes in routing

This commit is contained in:
Ryan Nowak 2014-11-17 17:23:38 -08:00
parent 661583f694
commit 38b3b61485
11 changed files with 87 additions and 49 deletions

View File

@ -15,7 +15,11 @@
{ {
<li> <li>
@parameter.Name - @(parameter?.Type?.FullName ?? "Unknown") - @parameter.Source.ToString() @parameter.Name - @(parameter?.Type?.FullName ?? "Unknown") - @parameter.Source.ToString()
- Constraint: @(parameter?.Constraint?.GetType()?.Name?.Replace("RouteConstraint", "") ?? " none") @if (parameter.Constraints != null && parameter.Constraints.Any())
{
var constraints = parameter.Constraints;
Write("-Constraint:" + string.Join(", ", constraints.Select(c => c.GetType()?.Name?.Replace("RouteConstraint", ""))));
}
- Default value: @(parameter?.DefaultValue ?? " none") - Default value: @(parameter?.DefaultValue ?? " none")
</li> </li>
} }

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections.Generic;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Routing; using Microsoft.AspNet.Routing;
@ -19,7 +20,7 @@ namespace Microsoft.AspNet.Mvc.Description
public ApiParameterSource Source { get; set; } public ApiParameterSource Source { get; set; }
public IRouteConstraint Constraint { get; set; } public IEnumerable<IRouteConstraint> Constraints { get; set; }
public object DefaultValue { get; set; } public object DefaultValue { get; set; }

View File

@ -180,7 +180,7 @@ namespace Microsoft.AspNet.Mvc.Description
if (action.AttributeRouteInfo != null && if (action.AttributeRouteInfo != null &&
action.AttributeRouteInfo.Template != null) action.AttributeRouteInfo.Template != null)
{ {
return TemplateParser.Parse(action.AttributeRouteInfo.Template, _constraintResolver); return TemplateParser.Parse(action.AttributeRouteInfo.Template);
} }
return null; return null;
@ -281,7 +281,7 @@ namespace Microsoft.AspNet.Mvc.Description
return resourceParameter; return resourceParameter;
} }
private static ApiParameterDescription CreateParameterFromTemplateAndParameterDescriptor( private ApiParameterDescription CreateParameterFromTemplateAndParameterDescriptor(
TemplatePart templateParameter, TemplatePart templateParameter,
ParameterDescriptor parameter) ParameterDescriptor parameter)
{ {
@ -291,7 +291,7 @@ namespace Microsoft.AspNet.Mvc.Description
IsOptional = parameter.IsOptional && IsOptionalParameter(templateParameter), IsOptional = parameter.IsOptional && IsOptionalParameter(templateParameter),
Name = parameter.Name, Name = parameter.Name,
ParameterDescriptor = parameter, ParameterDescriptor = parameter,
Constraint = templateParameter.InlineConstraint, Constraints = GetConstraints(_constraintResolver, templateParameter.InlineConstraints),
DefaultValue = templateParameter.DefaultValue, DefaultValue = templateParameter.DefaultValue,
Type = parameter.ParameterType, Type = parameter.ParameterType,
}; };
@ -299,12 +299,23 @@ namespace Microsoft.AspNet.Mvc.Description
return resourceParameter; return resourceParameter;
} }
private static IEnumerable<IRouteConstraint> GetConstraints(
IInlineConstraintResolver constraintResolver,
IEnumerable<InlineConstraint> constraints)
{
return
constraints
.Select(c => constraintResolver.ResolveConstraint(c.Constraint))
.Where(c => c != null)
.ToArray();
}
private static bool IsOptionalParameter(TemplatePart templateParameter) private static bool IsOptionalParameter(TemplatePart templateParameter)
{ {
return templateParameter.IsOptional || templateParameter.DefaultValue != null; return templateParameter.IsOptional || templateParameter.DefaultValue != null;
} }
private static ApiParameterDescription CreateParameterFromTemplate(TemplatePart templateParameter) private ApiParameterDescription CreateParameterFromTemplate(TemplatePart templateParameter)
{ {
return new ApiParameterDescription return new ApiParameterDescription
{ {
@ -312,7 +323,7 @@ namespace Microsoft.AspNet.Mvc.Description
IsOptional = IsOptionalParameter(templateParameter), IsOptional = IsOptionalParameter(templateParameter),
Name = templateParameter.Name, Name = templateParameter.Name,
ParameterDescriptor = null, ParameterDescriptor = null,
Constraint = templateParameter.InlineConstraint, Constraints = GetConstraints(_constraintResolver, templateParameter.InlineConstraints),
DefaultValue = templateParameter.DefaultValue, DefaultValue = templateParameter.DefaultValue,
}; };
} }

View File

@ -21,12 +21,12 @@ namespace Microsoft.AspNet.Mvc.Routing
/// <summary> /// <summary>
/// The route constraints. /// The route constraints.
/// </summary> /// </summary>
public IDictionary<string, IRouteConstraint> Constraints { get; set; } public IReadOnlyDictionary<string, IRouteConstraint> Constraints { get; set; }
/// <summary> /// <summary>
/// The route defaults. /// The route defaults.
/// </summary> /// </summary>
public IDictionary<string, object> Defaults { get; set; } public IReadOnlyDictionary<string, object> Defaults { get; set; }
/// <summary> /// <summary>
/// The order of the template. /// The order of the template.

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.Contracts; using System.Diagnostics.Contracts;
using System.Linq;
using Microsoft.AspNet.Routing.Template; using Microsoft.AspNet.Routing.Template;
namespace Microsoft.AspNet.Mvc.Routing namespace Microsoft.AspNet.Mvc.Routing
@ -59,7 +60,7 @@ namespace Microsoft.AspNet.Mvc.Routing
// If there is a route constraint for the parameter, reduce order by 1 // If there is a route constraint for the parameter, reduce order by 1
// Constrained parameters end up with order 2, Constrained catch alls end up with order 4 // Constrained parameters end up with order 2, Constrained catch alls end up with order 4
if (part.InlineConstraint != null) if (part.InlineConstraints != null && part.InlineConstraints.Any())
{ {
digit--; digit--;
} }

View File

@ -184,7 +184,7 @@ namespace Microsoft.AspNet.Mvc.Routing
if (!templateCache.TryGetValue(action.AttributeRouteInfo.Template, out parsedTemplate)) if (!templateCache.TryGetValue(action.AttributeRouteInfo.Template, out parsedTemplate))
{ {
// Parsing with throw if the template is invalid. // Parsing with throw if the template is invalid.
parsedTemplate = TemplateParser.Parse(action.AttributeRouteInfo.Template, constraintResolver); parsedTemplate = TemplateParser.Parse(action.AttributeRouteInfo.Template);
templateCache.Add(action.AttributeRouteInfo.Template, parsedTemplate); templateCache.Add(action.AttributeRouteInfo.Template, parsedTemplate);
} }
@ -218,9 +218,20 @@ namespace Microsoft.AspNet.Mvc.Routing
routeInfo.Name = action.AttributeRouteInfo.Name; routeInfo.Name = action.AttributeRouteInfo.Name;
routeInfo.Constraints = routeInfo.ParsedTemplate.Parameters var constraintBuilder = new RouteConstraintBuilder(constraintResolver, routeInfo.RouteTemplate);
.Where(p => p.InlineConstraint != null)
.ToDictionary(p => p.Name, p => p.InlineConstraint, StringComparer.OrdinalIgnoreCase); foreach (var parameter in routeInfo.ParsedTemplate.Parameters)
{
if (parameter.InlineConstraints != null)
{
foreach (var inlineConstraint in parameter.InlineConstraints)
{
constraintBuilder.AddResolvedConstraint(parameter.Name, inlineConstraint.Constraint);
}
}
}
routeInfo.Constraints = constraintBuilder.Build();
routeInfo.Defaults = routeInfo.ParsedTemplate.Parameters routeInfo.Defaults = routeInfo.ParsedTemplate.Parameters
.Where(p => p.DefaultValue != null) .Where(p => p.DefaultValue != null)
@ -233,9 +244,9 @@ namespace Microsoft.AspNet.Mvc.Routing
{ {
public ActionDescriptor ActionDescriptor { get; set; } public ActionDescriptor ActionDescriptor { get; set; }
public IDictionary<string, IRouteConstraint> Constraints { get; set; } public IReadOnlyDictionary<string, IRouteConstraint> Constraints { get; set; }
public IDictionary<string, object> Defaults { get; set; } public IReadOnlyDictionary<string, object> Defaults { get; set; }
public string ErrorMessage { get; set; } public string ErrorMessage { get; set; }

View File

@ -188,7 +188,7 @@ namespace Microsoft.AspNet.Mvc.Description
if (constraintType != null) if (constraintType != null)
{ {
Assert.IsType(constraintType, parameter.Constraint); Assert.IsType(constraintType, Assert.Single(parameter.Constraints));
} }
if (defaultValue != null) if (defaultValue != null)
@ -243,7 +243,7 @@ namespace Microsoft.AspNet.Mvc.Description
if (constraintType != null) if (constraintType != null)
{ {
Assert.IsType(constraintType, parameter.Constraint); Assert.IsType(constraintType, Assert.Single(parameter.Constraints));
} }
if (defaultValue != null) if (defaultValue != null)
@ -303,7 +303,7 @@ namespace Microsoft.AspNet.Mvc.Description
if (constraintType != null) if (constraintType != null)
{ {
Assert.IsType(constraintType, pathParameter.Constraint); Assert.IsType(constraintType, Assert.Single(pathParameter.Constraints));
} }
if (defaultValue != null) if (defaultValue != null)
@ -388,11 +388,11 @@ namespace Microsoft.AspNet.Mvc.Description
var description = Assert.Single(descriptions); var description = Assert.Single(descriptions);
var id1 = Assert.Single(description.ParameterDescriptions, p => p.Name == "id1"); var id1 = Assert.Single(description.ParameterDescriptions, p => p.Name == "id1");
Assert.Equal(ApiParameterSource.Path, id1.Source); Assert.Equal(ApiParameterSource.Path, id1.Source);
Assert.Null(id1.Constraint); Assert.Empty(id1.Constraints);
var id2 = Assert.Single(description.ParameterDescriptions, p => p.Name == "id2"); var id2 = Assert.Single(description.ParameterDescriptions, p => p.Name == "id2");
Assert.Equal(ApiParameterSource.Path, id2.Source); Assert.Equal(ApiParameterSource.Path, id2.Source);
Assert.IsType<IntRouteConstraint>(id2.Constraint); Assert.IsType<IntRouteConstraint>(Assert.Single(id2.Constraints));
} }
[Fact] [Fact]

View File

@ -63,11 +63,7 @@ namespace Microsoft.AspNet.Mvc.Routing
var options = new Mock<IOptions<RouteOptions>>(); var options = new Mock<IOptions<RouteOptions>>();
options.SetupGet(o => o.Options).Returns(new RouteOptions()); options.SetupGet(o => o.Options).Returns(new RouteOptions());
var constraintResolver = new DefaultInlineConstraintResolver( var parsed = TemplateParser.Parse(template);
Mock.Of<IServiceProvider>(),
options.Object);
var parsed = TemplateParser.Parse(template, constraintResolver);
return AttributeRoutePrecedence.Compute(parsed); return AttributeRoutePrecedence.Compute(parsed);
} }
} }

View File

@ -1256,18 +1256,21 @@ namespace Microsoft.AspNet.Mvc.Routing
private static AttributeRouteMatchingEntry CreateMatchingEntry(IRouter router, string template, int order) private static AttributeRouteMatchingEntry CreateMatchingEntry(IRouter router, string template, int order)
{ {
var constraintResolver = CreateConstraintResolver(); var routeGroup = string.Format("{0}&&{1}", order, template);
var routeTemplate = TemplateParser.Parse(template, constraintResolver);
var entry = new AttributeRouteMatchingEntry(); var entry = new AttributeRouteMatchingEntry();
entry.Route = new TemplateRoute(router, template, constraintResolver); entry.Route = new TemplateRoute(
target: router,
routeTemplate: template,
defaults: new RouteValueDictionary(new { test_route_group = routeGroup }),
constraints: null,
dataTokens: null,
inlineConstraintResolver: CreateConstraintResolver());
var routeTemplate = TemplateParser.Parse(template);
entry.Precedence = AttributeRoutePrecedence.Compute(routeTemplate); entry.Precedence = AttributeRoutePrecedence.Compute(routeTemplate);
entry.Order = order; entry.Order = order;
string routeGroup = string.Format("{0}&&{1}", order, template);
entry.Route.Defaults.Add("test_route_group", routeGroup);
return entry; return entry;
} }
@ -1281,15 +1284,25 @@ namespace Microsoft.AspNet.Mvc.Routing
var entry = new AttributeRouteLinkGenerationEntry(); var entry = new AttributeRouteLinkGenerationEntry();
entry.TemplateText = template; entry.TemplateText = template;
entry.Template = TemplateParser.Parse(template, constraintResolver); entry.Template = TemplateParser.Parse(template);
var defaults = entry.Template.Parameters var defaults = entry.Template.Parameters
.Where(p => p.DefaultValue != null) .Where(p => p.DefaultValue != null)
.ToDictionary(p => p.Name, p => p.DefaultValue); .ToDictionary(p => p.Name, p => p.DefaultValue);
var constraints = entry.Template.Parameters var constraintBuilder = new RouteConstraintBuilder(CreateConstraintResolver(), template);
.Where(p => p.InlineConstraint != null) foreach (var parameter in entry.Template.Parameters)
.ToDictionary(p => p.Name, p => p.InlineConstraint); {
if (parameter.InlineConstraints != null)
{
foreach (var constraint in parameter.InlineConstraints)
{
constraintBuilder.AddResolvedConstraint(parameter.Name, constraint.Constraint);
}
}
}
var constraints = constraintBuilder.Build();
entry.Constraints = constraints; entry.Constraints = constraints;
entry.Defaults = defaults; entry.Defaults = defaults;

View File

@ -178,7 +178,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
Assert.Equal("id", parameter.Name); Assert.Equal("id", parameter.Name);
Assert.False(parameter.IsOptional); Assert.False(parameter.IsOptional);
Assert.Equal("Path", parameter.Source); Assert.Equal("Path", parameter.Source);
Assert.Null(parameter.ConstraintType); Assert.Empty(parameter.ConstraintTypes);
} }
[Fact] [Fact]
@ -203,7 +203,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
Assert.Equal("integer", parameter.Name); Assert.Equal("integer", parameter.Name);
Assert.False(parameter.IsOptional); Assert.False(parameter.IsOptional);
Assert.Equal("Path", parameter.Source); Assert.Equal("Path", parameter.Source);
Assert.Equal("IntRouteConstraint", parameter.ConstraintType); Assert.Equal("IntRouteConstraint", Assert.Single(parameter.ConstraintTypes));
} }
[Fact] [Fact]
@ -254,7 +254,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
Assert.Equal("integer", parameter.Name); Assert.Equal("integer", parameter.Name);
Assert.False(parameter.IsOptional); Assert.False(parameter.IsOptional);
Assert.Equal("Path", parameter.Source); Assert.Equal("Path", parameter.Source);
Assert.Equal("IntRouteConstraint", parameter.ConstraintType); Assert.Equal("IntRouteConstraint", Assert.Single(parameter.ConstraintTypes));
} }
[Fact] [Fact]
@ -283,17 +283,17 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
var month = Assert.Single(description.ParameterDescriptions, p => p.Name == "month"); var month = Assert.Single(description.ParameterDescriptions, p => p.Name == "month");
Assert.False(month.IsOptional); Assert.False(month.IsOptional);
Assert.Equal("Path", month.Source); Assert.Equal("Path", month.Source);
Assert.Equal("RangeRouteConstraint", month.ConstraintType); Assert.Equal("RangeRouteConstraint", Assert.Single(month.ConstraintTypes));
var day = Assert.Single(description.ParameterDescriptions, p => p.Name == "day"); var day = Assert.Single(description.ParameterDescriptions, p => p.Name == "day");
Assert.False(day.IsOptional); Assert.False(day.IsOptional);
Assert.Equal("Path", day.Source); Assert.Equal("Path", day.Source);
Assert.Equal("IntRouteConstraint", day.ConstraintType); Assert.Equal("IntRouteConstraint", Assert.Single(day.ConstraintTypes));
var year = Assert.Single(description.ParameterDescriptions, p => p.Name == "year"); var year = Assert.Single(description.ParameterDescriptions, p => p.Name == "year");
Assert.False(year.IsOptional); Assert.False(year.IsOptional);
Assert.Equal("Path", year.Source); Assert.Equal("Path", year.Source);
Assert.Equal("IntRouteConstraint", year.ConstraintType); Assert.Equal("IntRouteConstraint", Assert.Single(year.ConstraintTypes));
} }
[Fact] [Fact]
@ -321,17 +321,17 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
var month = Assert.Single(description.ParameterDescriptions, p => p.Name == "month"); var month = Assert.Single(description.ParameterDescriptions, p => p.Name == "month");
Assert.False(month.IsOptional); Assert.False(month.IsOptional);
Assert.Equal("Path", month.Source); Assert.Equal("Path", month.Source);
Assert.Equal("RangeRouteConstraint", month.ConstraintType); Assert.Equal("RangeRouteConstraint", Assert.Single(month.ConstraintTypes));
var day = Assert.Single(description.ParameterDescriptions, p => p.Name == "day"); var day = Assert.Single(description.ParameterDescriptions, p => p.Name == "day");
Assert.False(day.IsOptional); Assert.False(day.IsOptional);
Assert.Equal("Path", day.Source); Assert.Equal("Path", day.Source);
Assert.Equal("IntRouteConstraint", day.ConstraintType); Assert.Equal("IntRouteConstraint", Assert.Single(day.ConstraintTypes));
var year = Assert.Single(description.ParameterDescriptions, p => p.Name == "year"); var year = Assert.Single(description.ParameterDescriptions, p => p.Name == "year");
Assert.True(year.IsOptional); Assert.True(year.IsOptional);
Assert.Equal("Path", year.Source); Assert.Equal("Path", year.Source);
Assert.Equal("IntRouteConstraint", year.ConstraintType); Assert.Equal("IntRouteConstraint", Assert.Single(year.ConstraintTypes));
} }
[Fact] [Fact]
@ -749,7 +749,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
public string Type { get; set; } public string Type { get; set; }
public string ConstraintType { get; set; } public string[] ConstraintTypes { get; set; }
} }
// Used to serialize data between client and server // Used to serialize data between client and server

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.Mvc; using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Description; using Microsoft.AspNet.Mvc.Description;
@ -56,7 +57,7 @@ namespace ApiExplorer
Name = parameter.Name, Name = parameter.Name,
Source = parameter.Source.ToString(), Source = parameter.Source.ToString(),
Type = parameter?.Type?.FullName, Type = parameter?.Type?.FullName,
ConstraintType = parameter?.Constraint?.GetType()?.Name, ConstraintTypes = parameter?.Constraints?.Select(c => c.GetType().Name).ToArray(),
}; };
data.ParameterDescriptions.Add(parameterData); data.ParameterDescriptions.Add(parameterData);
@ -103,7 +104,7 @@ namespace ApiExplorer
public string Type { get; set; } public string Type { get; set; }
public string ConstraintType { get; set; } public string[] ConstraintTypes { get; set; }
} }
// Used to serialize data between client and server // Used to serialize data between client and server