diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionDescriptor.cs b/src/Microsoft.AspNet.Mvc.Core/ActionDescriptor.cs index fdee103a14..eadf1bf6ef 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionDescriptor.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionDescriptor.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using Microsoft.AspNet.Mvc.Routing; namespace Microsoft.AspNet.Mvc { @@ -17,15 +18,9 @@ namespace Microsoft.AspNet.Mvc public List RouteConstraints { get; set; } - /// - /// The set of route values that are added when this action is selected. - /// - public Dictionary RouteValueDefaults { get; private set; } + public AttributeRouteInfo AttributeRouteInfo { get; set; } - /// - /// The attribute route template. May be null if the action has no attribute routes. - /// - public string AttributeRouteTemplate { get; set; } + public Dictionary RouteValueDefaults { get; private set; } public List MethodConstraints { get; set; } diff --git a/src/Microsoft.AspNet.Mvc.Core/ReflectedActionDescriptorProvider.cs b/src/Microsoft.AspNet.Mvc.Core/ReflectedActionDescriptorProvider.cs index b0abaf3b0d..0d9eb23a51 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ReflectedActionDescriptorProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ReflectedActionDescriptorProvider.cs @@ -146,6 +146,15 @@ namespace Microsoft.AspNet.Mvc }); } + var combinedRoute = ReflectedAttributeRouteModel.CombineReflectedAttributeRouteModel( + controller.AttributeRouteModel, + action.AttributeRouteModel); + + var attributeRouteInfo = combinedRoute == null ? null : new AttributeRouteInfo() + { + Template = combinedRoute.Template + }; + var actionDescriptor = new ReflectedActionDescriptor() { Name = action.ActionName, @@ -153,6 +162,7 @@ namespace Microsoft.AspNet.Mvc MethodInfo = action.ActionMethod, Parameters = parameterDescriptors, RouteConstraints = new List(), + AttributeRouteInfo = attributeRouteInfo }; actionDescriptor.DisplayName = string.Format( @@ -202,11 +212,8 @@ namespace Microsoft.AspNet.Mvc } } - var templateText = AttributeRouteTemplate.Combine( - controller.RouteTemplate, - action.RouteTemplate); - - if (templateText != null) + if (actionDescriptor.AttributeRouteInfo != null && + actionDescriptor.AttributeRouteInfo.Template != null) { // An attribute routed action will ignore conventional routed constraints. We still // want to provide these values as ambient values. @@ -217,9 +224,10 @@ namespace Microsoft.AspNet.Mvc // Replaces tokens like [controller]/[action] in the route template with the actual values // for this action. + var templateText = actionDescriptor.AttributeRouteInfo.Template; try { - templateText = AttributeRouteTemplate.ReplaceTokens( + templateText = ReflectedAttributeRouteModel.ReplaceTokens( templateText, actionDescriptor.RouteValueDefaults); } @@ -233,7 +241,7 @@ namespace Microsoft.AspNet.Mvc routeTemplateErrors.Add(message); } - actionDescriptor.AttributeRouteTemplate = templateText; + actionDescriptor.AttributeRouteInfo.Template = templateText; // An attribute routed action is matched by its 'route group' which identifies all equivalent // actions. @@ -261,40 +269,41 @@ namespace Microsoft.AspNet.Mvc actions.Add(actionDescriptor); } - } - foreach (var actionDescriptor in actions) - { - foreach (var key in removalConstraints) + foreach (var actionDescriptor in actions) { - if (actionDescriptor.AttributeRouteTemplate == null) + foreach (var key in removalConstraints) { - // Any any attribute routes are in use, then non-attribute-routed ADs can't be selected - // when a route group returned by the route. - if (routeGroupsByTemplate.Any()) + if (actionDescriptor.AttributeRouteInfo == null || + actionDescriptor.AttributeRouteInfo.Template == null) { - actionDescriptor.RouteConstraints.Add(new RouteDataActionConstraint( - AttributeRouting.RouteGroupKey, - RouteKeyHandling.DenyKey)); - } + // Any any attribute routes are in use, then non-attribute-routed ADs can't be selected + // when a route group returned by the route. + if (routeGroupsByTemplate.Any()) + { + actionDescriptor.RouteConstraints.Add(new RouteDataActionConstraint( + AttributeRouting.RouteGroupKey, + RouteKeyHandling.DenyKey)); + } - if (!HasConstraint(actionDescriptor.RouteConstraints, key)) - { - actionDescriptor.RouteConstraints.Add(new RouteDataActionConstraint( - key, - RouteKeyHandling.DenyKey)); + if (!HasConstraint(actionDescriptor.RouteConstraints, key)) + { + actionDescriptor.RouteConstraints.Add(new RouteDataActionConstraint( + key, + RouteKeyHandling.DenyKey)); + } } - } - else - { - // We still want to add a 'null' for any constraint with DenyKey so that link generation - // works properly. - // - // Consider an action like { area = "", controller = "Home", action = "Index" }. Even if - // it's attribute routed, it needs to know that area must be null to generate a link. - if (!actionDescriptor.RouteValueDefaults.ContainsKey(key)) + else { - actionDescriptor.RouteValueDefaults.Add(key, null); + // We still want to add a 'null' for any constraint with DenyKey so that link generation + // works properly. + // + // Consider an action like { area = "", controller = "Home", action = "Index" }. Even if + // it's attribute routed, it needs to know that area must be null to generate a link. + if (!actionDescriptor.RouteValueDefaults.ContainsKey(key)) + { + actionDescriptor.RouteValueDefaults.Add(key, null); + } } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ReflectedModelBuilder/ReflectedActionModel.cs b/src/Microsoft.AspNet.Mvc.Core/ReflectedModelBuilder/ReflectedActionModel.cs index fc3b82f9c9..41b186be57 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ReflectedModelBuilder/ReflectedActionModel.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ReflectedModelBuilder/ReflectedActionModel.cs @@ -23,7 +23,7 @@ namespace Microsoft.AspNet.Mvc.ReflectedModelBuilder var routeTemplateAttribute = Attributes.OfType().FirstOrDefault(); if (routeTemplateAttribute != null) { - RouteTemplate = routeTemplateAttribute.Template; + AttributeRouteModel = new ReflectedAttributeRouteModel(routeTemplateAttribute); } HttpMethods = new List(); @@ -44,6 +44,6 @@ namespace Microsoft.AspNet.Mvc.ReflectedModelBuilder public List Parameters { get; private set; } - public string RouteTemplate { get; set; } + public ReflectedAttributeRouteModel AttributeRouteModel { get; set; } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouteTemplate.cs b/src/Microsoft.AspNet.Mvc.Core/ReflectedModelBuilder/ReflectedAttributeRouteModel.cs similarity index 86% rename from src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouteTemplate.cs rename to src/Microsoft.AspNet.Mvc.Core/ReflectedModelBuilder/ReflectedAttributeRouteModel.cs index 720e26ef4c..875677a030 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouteTemplate.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ReflectedModelBuilder/ReflectedAttributeRouteModel.cs @@ -5,21 +5,62 @@ using System; using System.Collections.Generic; using System.Text; using Microsoft.AspNet.Mvc.Core; +using Microsoft.AspNet.Mvc.Routing; -namespace Microsoft.AspNet.Mvc.Routing +namespace Microsoft.AspNet.Mvc.ReflectedModelBuilder { - /// - /// Functionality supporting route templates for attribute routes. - /// - public static class AttributeRouteTemplate + public class ReflectedAttributeRouteModel { + private static readonly ReflectedAttributeRouteModel _default = new ReflectedAttributeRouteModel(); + + public ReflectedAttributeRouteModel() + { + } + + public ReflectedAttributeRouteModel([NotNull] IRouteTemplateProvider templateProvider) + { + Template = templateProvider.Template; + } + + public string Template { get; set; } + + /// + /// Combines two instances and returns + /// a new instance with the result. + /// + /// The left . + /// The right . + /// A new instance of that represents the + /// combination of the two instances or null if both + /// parameters are null. + public static ReflectedAttributeRouteModel CombineReflectedAttributeRouteModel( + ReflectedAttributeRouteModel left, + ReflectedAttributeRouteModel right) + { + left = left ?? _default; + right = right ?? _default; + + var template = CombineTemplates(left.Template, right.Template); + + // The action is not attribute routed. + if (template == null) + { + return null; + } + + return new ReflectedAttributeRouteModel() + { + Template = template + }; + } + /// /// Combines attribute routing templates. /// /// The left template. /// The right template. /// A combined template. - public static string Combine(string left, string right) + public static string CombineTemplates(string left, string right) { var result = CombineCore(left, right); return CleanTemplate(result); diff --git a/src/Microsoft.AspNet.Mvc.Core/ReflectedModelBuilder/ReflectedControllerModel.cs b/src/Microsoft.AspNet.Mvc.Core/ReflectedModelBuilder/ReflectedControllerModel.cs index b0398a2f6e..816d36abc8 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ReflectedModelBuilder/ReflectedControllerModel.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ReflectedModelBuilder/ReflectedControllerModel.cs @@ -27,7 +27,7 @@ namespace Microsoft.AspNet.Mvc.ReflectedModelBuilder var routeTemplateAttribute = Attributes.OfType().FirstOrDefault(); if (routeTemplateAttribute != null) { - RouteTemplate = routeTemplateAttribute.Template; + AttributeRouteModel = new ReflectedAttributeRouteModel(routeTemplateAttribute); } ControllerName = controllerType.Name.EndsWith("Controller", StringComparison.Ordinal) @@ -47,6 +47,6 @@ namespace Microsoft.AspNet.Mvc.ReflectedModelBuilder public List RouteConstraints { get; private set; } - public string RouteTemplate { get; set; } + public ReflectedAttributeRouteModel AttributeRouteModel { get; set; } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouteInfo.cs b/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouteInfo.cs new file mode 100644 index 0000000000..f8ba92e7d9 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouteInfo.cs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.Mvc.Routing +{ + /// + /// Represents the routing information for an action that is attribute routed. + /// + public class AttributeRouteInfo + { + /// + /// The route template. May be null if the action has no attribute routes. + /// + public string Template { get; set; } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouting.cs b/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouting.cs index 1d58af6bc7..d7cbecdebb 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouting.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouting.cs @@ -115,7 +115,9 @@ namespace Microsoft.AspNet.Mvc.Routing // of memory, so sharing is worthwhile. var templateCache = new Dictionary(StringComparer.OrdinalIgnoreCase); - foreach (var action in actions.Where(a => a.AttributeRouteTemplate != null)) + var attributeRoutedActions = actions.Where(a => a.AttributeRouteInfo != null && + a.AttributeRouteInfo.Template != null); + foreach (var action in attributeRoutedActions) { var routeInfo = GetRouteInfo(constraintResolver, templateCache, action); if (routeInfo.ErrorMessage == null) @@ -169,17 +171,17 @@ namespace Microsoft.AspNet.Mvc.Routing { ActionDescriptor = action, RouteGroup = constraint.RouteValue, - RouteTemplate = action.AttributeRouteTemplate, + RouteTemplate = action.AttributeRouteInfo.Template, }; try { RouteTemplate parsedTemplate; - if (!templateCache.TryGetValue(action.AttributeRouteTemplate, out parsedTemplate)) + if (!templateCache.TryGetValue(action.AttributeRouteInfo.Template, out parsedTemplate)) { // Parsing with throw if the template is invalid. - parsedTemplate = TemplateParser.Parse(action.AttributeRouteTemplate, constraintResolver); - templateCache.Add(action.AttributeRouteTemplate, parsedTemplate); + parsedTemplate = TemplateParser.Parse(action.AttributeRouteInfo.Template, constraintResolver); + templateCache.Add(action.AttributeRouteInfo.Template, parsedTemplate); } routeInfo.ParsedTemplate = parsedTemplate; diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedActionDescriptorProviderTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedActionDescriptorProviderTests.cs index ff0afd091f..68bdc0fc5b 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedActionDescriptorProviderTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedActionDescriptorProviderTests.cs @@ -220,10 +220,10 @@ namespace Microsoft.AspNet.Mvc.Test // Assert var controller = Assert.Single(model.Controllers); - Assert.Equal("api/Token/[key]/[controller]", controller.RouteTemplate); + Assert.Equal("api/Token/[key]/[controller]", controller.AttributeRouteModel.Template); var action = Assert.Single(controller.Actions); - Assert.Equal("stub/[action]", action.RouteTemplate); + Assert.Equal("stub/[action]", action.AttributeRouteModel.Template); } [Fact] @@ -237,7 +237,7 @@ namespace Microsoft.AspNet.Mvc.Test // Assert var action = Assert.Single(actions); - Assert.Equal("api/Token/value/TokenReplacement/stub/ThisIsAnAction", action.AttributeRouteTemplate); + Assert.Equal("api/Token/value/TokenReplacement/stub/ThisIsAnAction", action.AttributeRouteInfo.Template); } [Fact] @@ -276,7 +276,7 @@ namespace Microsoft.AspNet.Mvc.Test // Assert var action = Assert.Single(actions); - Assert.Equal("stub/ThisIsAnAction", action.AttributeRouteTemplate); + Assert.Equal("stub/ThisIsAnAction", action.AttributeRouteInfo.Template); } // Token replacement happens before we 'group' routes. So two route templates @@ -314,7 +314,7 @@ namespace Microsoft.AspNet.Mvc.Test // Assert var action = Assert.Single(actions); - Assert.Equal("stub/{controller}/{action}", action.AttributeRouteTemplate); + Assert.Equal("stub/{controller}/{action}", action.AttributeRouteInfo.Template); } private ReflectedActionDescriptorProvider GetProvider( diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedModelBuilder/ReflectedActionModelTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedModelBuilder/ReflectedActionModelTests.cs index 358fd4323f..3e14da0b50 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedModelBuilder/ReflectedActionModelTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedModelBuilder/ReflectedActionModelTests.cs @@ -18,9 +18,10 @@ namespace Microsoft.AspNet.Mvc.ReflectedModelBuilder.Test var model = new ReflectedActionModel(actionMethod); // Assert - Assert.Equal(2, model.Attributes.Count); + Assert.Equal(3, model.Attributes.Count); Assert.Single(model.Attributes, a => a is MyFilterAttribute); Assert.Single(model.Attributes, a => a is MyOtherAttribute); + Assert.Single(model.Attributes, a => a is HttpGetAttribute); } [Fact] @@ -37,10 +38,25 @@ namespace Microsoft.AspNet.Mvc.ReflectedModelBuilder.Test Assert.IsType(model.Filters[0]); } + [Fact] + public void ReflectedActionModel_PopulatesAttributeRouteInfo() + { + // Arrange + var actionMethod = typeof(BlogController).GetMethod("Edit"); + + // Act + var model = new ReflectedActionModel(actionMethod); + + // Assert + Assert.NotNull(model.AttributeRouteModel); + Assert.Equal("Edit", model.AttributeRouteModel.Template); + } + private class BlogController { [MyOther] [MyFilter] + [HttpGet("Edit")] public void Edit() { } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Routing/AttributeRouteTemplateTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedModelBuilder/ReflectedAttributeRouteModelTests.cs similarity index 76% rename from test/Microsoft.AspNet.Mvc.Core.Test/Routing/AttributeRouteTemplateTests.cs rename to test/Microsoft.AspNet.Mvc.Core.Test/ReflectedModelBuilder/ReflectedAttributeRouteModelTests.cs index aaaf4a0b8a..8f5647aa59 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Routing/AttributeRouteTemplateTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedModelBuilder/ReflectedAttributeRouteModelTests.cs @@ -6,9 +6,9 @@ using System; using System.Collections.Generic; using Xunit; -namespace Microsoft.AspNet.Mvc.Routing +namespace Microsoft.AspNet.Mvc.ReflectedModelBuilder { - public class AttributeRouteTemplateTests + public class ReflectedAttributeRouteModelTests { [Theory] [InlineData(null, null, null)] @@ -30,7 +30,7 @@ namespace Microsoft.AspNet.Mvc.Routing public void Combine_EmptyTemplates(string left, string right, string expected) { // Arrange & Act - var combined = AttributeRouteTemplate.Combine(left, right); + var combined = ReflectedAttributeRouteModel.CombineTemplates(left, right); // Assert Assert.Equal(expected, combined); @@ -55,7 +55,7 @@ namespace Microsoft.AspNet.Mvc.Routing public void Combine_OneTemplateHasValue(string left, string right, string expected) { // Arrange & Act - var combined = AttributeRouteTemplate.Combine(left, right); + var combined = ReflectedAttributeRouteModel.CombineTemplates(left, right); // Assert Assert.Equal(expected, combined); @@ -71,7 +71,7 @@ namespace Microsoft.AspNet.Mvc.Routing public void Combine_BothTemplatesHasValue(string left, string right, string expected) { // Arrange & Act - var combined = AttributeRouteTemplate.Combine(left, right); + var combined = ReflectedAttributeRouteModel.CombineTemplates(left, right); // Assert Assert.Equal(expected, combined); @@ -95,7 +95,7 @@ namespace Microsoft.AspNet.Mvc.Routing public void Combine_InvalidTemplates(string left, string right, string expected) { // Arrange & Act - var combined = AttributeRouteTemplate.Combine(left, right); + var combined = ReflectedAttributeRouteModel.CombineTemplates(left, right); // Assert Assert.Equal(expected, combined); @@ -194,7 +194,7 @@ namespace Microsoft.AspNet.Mvc.Routing } // Act - var result = AttributeRouteTemplate.ReplaceTokens(template, valuesDictionary); + var result = ReflectedAttributeRouteModel.ReplaceTokens(template, valuesDictionary); // Assert Assert.Equal(expected, result); @@ -283,7 +283,7 @@ namespace Microsoft.AspNet.Mvc.Routing // Act var ex = Assert.Throws( - () => { AttributeRouteTemplate.ReplaceTokens(template, valuesDictionary); }); + () => { ReflectedAttributeRouteModel.ReplaceTokens(template, valuesDictionary); }); // Assert Assert.Equal(expected, ex.Message); @@ -308,10 +308,74 @@ namespace Microsoft.AspNet.Mvc.Routing // Act var ex = Assert.Throws( - () => { AttributeRouteTemplate.ReplaceTokens(template, values); }); + () => { ReflectedAttributeRouteModel.ReplaceTokens(template, values); }); // Assert Assert.Equal(expected, ex.Message); } + + [Theory] + [MemberData("ValidReflectedAttributeRouteModelsTestData")] + public void Combine_ValidReflectedAttributeRouteModels( + ReflectedAttributeRouteModel left, + ReflectedAttributeRouteModel right, + ReflectedAttributeRouteModel expectedResult) + { + // Arrange & Act + var combined = ReflectedAttributeRouteModel.CombineReflectedAttributeRouteModel(left, right); + + // Assert + Assert.NotNull(combined); + Assert.Equal(expectedResult.Template, combined.Template); + } + + [Theory] + [MemberData("NullOrNullTemplateReflectedAttributeRouteModelTestData")] + public void Combine_NullOrNullTemplateReflectedAttributeRouteModels( + ReflectedAttributeRouteModel left, + ReflectedAttributeRouteModel right) + { + // Arrange & Act + var combined = ReflectedAttributeRouteModel.CombineReflectedAttributeRouteModel(left, right); + + // Assert + Assert.Null(combined); + } + + public static IEnumerable NullOrNullTemplateReflectedAttributeRouteModelTestData + { + get + { + var data = new TheoryData(); + data.Add(null, null); + data.Add(null, Create(null)); + data.Add(Create(null), null); + data.Add(Create(null), Create(null)); + + return data; + } + } + + public static IEnumerable ValidReflectedAttributeRouteModelsTestData + { + get + { + var data = new TheoryData(); + data.Add(null, Create("Index"), Create("Index")); + data.Add(Create("Home"), null, Create("Home")); + data.Add(Create("Home"), Create("Index"), Create("Home/Index")); + data.Add(Create("Blog"), Create("/Index"), Create("Index")); + + return data; + } + } + + private static ReflectedAttributeRouteModel Create(string template) + { + return new ReflectedAttributeRouteModel + { + Template = template + }; + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedModelBuilder/ReflectedControllerModelTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedModelBuilder/ReflectedControllerModelTests.cs index bca2dfc73e..b3664d283d 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedModelBuilder/ReflectedControllerModelTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedModelBuilder/ReflectedControllerModelTests.cs @@ -19,11 +19,12 @@ namespace Microsoft.AspNet.Mvc.ReflectedModelBuilder.Test var model = new ReflectedControllerModel(controllerType.GetTypeInfo()); // Assert - Assert.Equal(3, model.Attributes.Count); + Assert.Equal(4, model.Attributes.Count); Assert.Single(model.Attributes, a => a is MyOtherAttribute); Assert.Single(model.Attributes, a => a is MyFilterAttribute); Assert.Single(model.Attributes, a => a is MyRouteConstraintAttribute); + Assert.Single(model.Attributes, a => a is RouteAttribute); } [Fact] @@ -80,9 +81,24 @@ namespace Microsoft.AspNet.Mvc.ReflectedModelBuilder.Test Assert.Equal("Store", model.ControllerName); } + [Fact] + public void ReflectedControllerModel_PopulatesAttributeRouteInfo() + { + // Arrange + var controllerType = typeof(BlogController); + + // Act + var model = new ReflectedControllerModel(controllerType.GetTypeInfo()); + + // Assert + Assert.NotNull(model.AttributeRouteModel); + Assert.Equal("Blog", model.AttributeRouteModel.Template); + } + [MyOther] [MyFilter] [MyRouteConstraint] + [Route("Blog")] private class BlogController { } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Routing/AttributeRoutingTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Routing/AttributeRoutingTest.cs index 85541b4502..3169f4139a 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Routing/AttributeRoutingTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Routing/AttributeRoutingTest.cs @@ -48,7 +48,7 @@ namespace Microsoft.AspNet.Mvc.Routing "The following errors occurred with attribute routing information:" + Environment.NewLine + Environment.NewLine + "For action: 'DisallowedParameter'" + Environment.NewLine + - "Error: The attribute route '{foo}/{action}' cannot contain a parameter named '{foo}'. " + + "Error: The attribute route '{foo}/{action}' cannot contain a parameter named '{foo}'. " + "Use '[foo]' in the route template to insert the value 'bleh'."; var router = CreateRouter(); @@ -106,7 +106,9 @@ namespace Microsoft.AspNet.Mvc.Routing { new RouteDataActionConstraint(AttributeRouting.RouteGroupKey, "group"), }; - action.AttributeRouteTemplate = "{controller}/{action}"; + action.AttributeRouteInfo = new AttributeRouteInfo(); + action.AttributeRouteInfo.Template = "{controller}/{action}"; + action.RouteValueDefaults.Add("controller", "Home"); action.RouteValueDefaults.Add("action", "Index"); @@ -136,7 +138,7 @@ namespace Microsoft.AspNet.Mvc.Routing { new RouteDataActionConstraint(AttributeRouting.RouteGroupKey, "whatever"), }, - AttributeRouteTemplate = template, + AttributeRouteInfo = new AttributeRouteInfo { Template = template }, }; }