Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: kamranayub/AttributeRouting
base: 4266990bfa
...
head fork: kamranayub/AttributeRouting
compare: 4c9e264ab8
  • 3 commits
  • 33 files changed
  • 0 commit comments
  • 1 contributor
Commits on Apr 07, 2012
@kamranayub Add specs for Web API: Conventions, Constraints, and StandardUsage 907df42
@kamranayub RouteDefaults specs for Web API 10c4194
@kamranayub RouteConvention spec fix and RoutePrecedence specs
Also fixed an issue where the MVC-based config was accepting promoted
controllers of the Api controller types
4c9e264
Showing with 996 additions and 98 deletions.
  1. +36 −0 src/AttributeRouting.Specs/AttributeRouting.Specs.csproj
  2. +17 −2 src/AttributeRouting.Specs/Features/RouteAreas.feature
  3. +48 −17 src/AttributeRouting.Specs/Features/RouteAreas.feature.cs
  4. +5 −1 src/AttributeRouting.Specs/Features/RouteConstraints.feature
  5. +23 −11 src/AttributeRouting.Specs/Features/RouteConstraints.feature.cs
  6. +43 −1 src/AttributeRouting.Specs/Features/RouteConventions.feature
  7. +114 −8 src/AttributeRouting.Specs/Features/RouteConventions.feature.cs
  8. +6 −0 src/AttributeRouting.Specs/Features/RouteDefaults.feature
  9. +27 −15 src/AttributeRouting.Specs/Features/RouteDefaults.feature.cs
  10. +33 −1 src/AttributeRouting.Specs/Features/RoutePrecedence.feature
  11. +108 −0 src/AttributeRouting.Specs/Features/RoutePrecedence.feature.cs
  12. +19 −1 src/AttributeRouting.Specs/Features/StandardUsage.feature
  13. +32 −0 src/AttributeRouting.Specs/Features/StandardUsage.feature.cs
  14. +17 −0 src/AttributeRouting.Specs/ScenarioContextExtensions.cs
  15. +1 −2  src/AttributeRouting.Specs/Steps/LoggingSteps.cs
  16. +15 −14 src/AttributeRouting.Specs/Steps/RouteConstraintSteps.cs
  17. +13 −8 src/AttributeRouting.Specs/Steps/RouteDefaultsSteps.cs
  18. +13 −0 src/AttributeRouting.Specs/Steps/RoutePrecedenceSteps.cs
  19. +2 −0  src/AttributeRouting.Specs/Steps/SharedSteps.cs
  20. +49 −0 src/AttributeRouting.Specs/Subjects/Http/RouteAreasControllers.cs
  21. +31 −0 src/AttributeRouting.Specs/Subjects/Http/RouteConstraintsController.cs
  22. +84 −0 src/AttributeRouting.Specs/Subjects/Http/RouteConventionsController.cs
  23. +36 −0 src/AttributeRouting.Specs/Subjects/Http/RouteDefaultsController.cs
  24. +87 −0 src/AttributeRouting.Specs/Subjects/Http/RoutePrecedenceController.cs
  25. +45 −0 src/AttributeRouting.Specs/Subjects/Http/StandardUsageController.cs
  26. +12 −7 src/AttributeRouting.Specs/packages.config
  27. +16 −0 src/AttributeRouting.Web.Http.SelfHost/Framework/AttributeRouteContainer.cs
  28. +16 −0 src/AttributeRouting.Web.Http.WebHost/Framework/AttributeRouteContainer.cs
  29. +6 −6 src/AttributeRouting.Web.Http/DefaultHttpRouteConventionAttribute.cs
  30. +16 −0 src/AttributeRouting.Web.Mvc/Framework/AttributeRouteContainer.cs
  31. +6 −3 src/AttributeRouting/AttributeRoutingConfiguration.cs
  32. +10 −1 src/AttributeRouting/Framework/AttributeRouteContainerBase.cs
  33. +10 −0 src/AttributeRouting/Framework/IAttributeRouteContainer.cs
View
36 src/AttributeRouting.Specs/AttributeRouting.Specs.csproj
@@ -53,8 +53,26 @@
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
+ <Reference Include="System.Json">
+ <HintPath>..\packages\System.Json.4.0.20126.16343\lib\net40\System.Json.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Net.Http">
+ <HintPath>..\packages\System.Net.Http.2.0.20126.16343\lib\net40\System.Net.Http.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Net.Http.Formatting">
+ <HintPath>..\packages\System.Net.Http.Formatting.4.0.20126.16343\lib\net40\System.Net.Http.Formatting.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Net.Http.WebRequest">
+ <HintPath>..\packages\System.Net.Http.2.0.20126.16343\lib\net40\System.Net.Http.WebRequest.dll</HintPath>
+ </Reference>
<Reference Include="System.Web" />
<Reference Include="System.Web.Abstractions" />
+ <Reference Include="System.Web.Http">
+ <HintPath>..\packages\AspNetWebApi.Core.4.0.20126.16343\lib\net40\System.Web.Http.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Web.Http.Common">
+ <HintPath>..\packages\System.Web.Http.Common.4.0.20126.16343\lib\net40\System.Web.Http.Common.dll</HintPath>
+ </Reference>
<Reference Include="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="System.Web.Routing" />
<Reference Include="System.Xml.Linq" />
@@ -116,6 +134,12 @@
<Compile Include="Steps\SharedSteps.cs" />
<Compile Include="Steps\StandardUsageSteps.cs" />
<Compile Include="Subjects\BugFixesController.cs" />
+ <Compile Include="Subjects\Http\RouteAreasControllers.cs" />
+ <Compile Include="Subjects\Http\RouteConstraintsController.cs" />
+ <Compile Include="Subjects\Http\RouteConventionsController.cs" />
+ <Compile Include="Subjects\Http\RouteDefaultsController.cs" />
+ <Compile Include="Subjects\Http\RoutePrecedenceController.cs" />
+ <Compile Include="Subjects\Http\StandardUsageController.cs" />
<Compile Include="Subjects\LowercaseUrlController.cs" />
<Compile Include="Subjects\RouteAreasControllers.cs" />
<Compile Include="Subjects\RoutePrefixesControllers.cs" />
@@ -179,6 +203,18 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\AttributeRouting.Web.Http.SelfHost\AttributeRouting.Web.Http.SelfHost.csproj">
+ <Project>{246F7AEC-9429-4FBB-8747-92A3F025C711}</Project>
+ <Name>AttributeRouting.Web.Http.SelfHost</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\AttributeRouting.Web.Http.WebHost\AttributeRouting.Web.Http.WebHost.csproj">
+ <Project>{A018FEC5-45F8-44FB-BB6C-33697B418434}</Project>
+ <Name>AttributeRouting.Web.Http.WebHost</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\AttributeRouting.Web.Http\AttributeRouting.Web.Http.csproj">
+ <Project>{CCDE9AD7-3822-4B0B-AA19-DF6698A85D3D}</Project>
+ <Name>AttributeRouting.Web.Http</Name>
+ </ProjectReference>
<ProjectReference Include="..\AttributeRouting.Web\AttributeRouting.Web.csproj">
<Project>{C91C065B-A821-4890-9F31-F9E245D804D1}</Project>
<Name>AttributeRouting.Web</Name>
View
19 src/AttributeRouting.Specs/Features/RouteAreas.feature
@@ -7,25 +7,40 @@ Scenario: Generating area routes
When I fetch the routes for the Areas controller's Index action
Then the route url is "Area/Index"
And the data token for "area" is "Area"
+ When I fetch the routes for the HttpAreas controller's Get action
+ Then the route url is "ApiArea/Get"
+ And the data token for "area" is "ApiArea"
Scenario: Generating area routes when route urls specify a duplicate area prefix
When I fetch the routes for the Areas controller's DuplicatePrefix action
Then the route url is "Area/DuplicatePrefix"
+ When I fetch the routes for the HttpAreas controller's DuplicatePrefix action
+ Then the route url is "ApiArea/DuplicatePrefix"
Scenario: Generating absolute routes when a route area is defined
When I fetch the routes for the Areas controller's Absolute action
Then the route url is "AreaAbsolute"
+ When I fetch the routes for the HttpAreas controller's Absolute action
+ Then the route url is "ApiAreaAbsolute"
Scenario: Generating area routes when route url starts with the area prefix
When I fetch the routes for the Areas controller's RouteBeginsWithAreaName action
Then the route url is "Area/Areas"
+ When I fetch the routes for the HttpAreas controller's RouteBeginsWithAreaName action
+ Then the route url is "ApiArea/ApiAreas"
Scenario: Generating area routes with an explicit area url
When I fetch the routes for the ExplicitAreaUrl controller's Index action
Then the route url is "ExplicitArea/Index"
And the data token for "area" is "Area"
-
+ When I fetch the routes for the HttpExplicitAreaUrl controller's Get action
+ Then the route url is "ApiExplicitArea/Get"
+ And the data token for "area" is "ApiArea"
+
Scenario: Generating area routes with an explicit area url when route urls specify a duplicate area prefix
When I fetch the routes for the ExplicitAreaUrl controller's DuplicatePrefix action
Then the route url is "ExplicitArea/DuplicatePrefix"
- And the data token for "area" is "Area"
+ And the data token for "area" is "Area"
+ When I fetch the routes for the HttpExplicitAreaUrl controller's DuplicatePrefix action
+ Then the route url is "ApiExplicitArea/DuplicatePrefix"
+ And the data token for "area" is "ApiArea"
View
65 src/AttributeRouting.Specs/Features/RouteAreas.feature.cs
@@ -87,6 +87,12 @@ public virtual void GeneratingAreaRoutes()
testRunner.Then("the route url is \"Area/Index\"");
#line 9
testRunner.And("the data token for \"area\" is \"Area\"");
+#line 10
+ testRunner.When("I fetch the routes for the HttpAreas controller\'s Get action");
+#line 11
+ testRunner.Then("the route url is \"ApiArea/Get\"");
+#line 12
+ testRunner.And("the data token for \"area\" is \"ApiArea\"");
#line hidden
this.ScenarioCleanup();
}
@@ -96,14 +102,18 @@ public virtual void GeneratingAreaRoutes()
public virtual void GeneratingAreaRoutesWhenRouteUrlsSpecifyADuplicateAreaPrefix()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Generating area routes when route urls specify a duplicate area prefix", ((string[])(null)));
-#line 11
+#line 14
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 12
+#line 15
testRunner.When("I fetch the routes for the Areas controller\'s DuplicatePrefix action");
-#line 13
+#line 16
testRunner.Then("the route url is \"Area/DuplicatePrefix\"");
+#line 17
+ testRunner.When("I fetch the routes for the HttpAreas controller\'s DuplicatePrefix action");
+#line 18
+ testRunner.Then("the route url is \"ApiArea/DuplicatePrefix\"");
#line hidden
this.ScenarioCleanup();
}
@@ -113,14 +123,18 @@ public virtual void GeneratingAreaRoutesWhenRouteUrlsSpecifyADuplicateAreaPrefix
public virtual void GeneratingAbsoluteRoutesWhenARouteAreaIsDefined()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Generating absolute routes when a route area is defined", ((string[])(null)));
-#line 15
+#line 20
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 16
+#line 21
testRunner.When("I fetch the routes for the Areas controller\'s Absolute action");
-#line 17
+#line 22
testRunner.Then("the route url is \"AreaAbsolute\"");
+#line 23
+ testRunner.When("I fetch the routes for the HttpAreas controller\'s Absolute action");
+#line 24
+ testRunner.Then("the route url is \"ApiAreaAbsolute\"");
#line hidden
this.ScenarioCleanup();
}
@@ -130,14 +144,18 @@ public virtual void GeneratingAbsoluteRoutesWhenARouteAreaIsDefined()
public virtual void GeneratingAreaRoutesWhenRouteUrlStartsWithTheAreaPrefix()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Generating area routes when route url starts with the area prefix", ((string[])(null)));
-#line 19
+#line 26
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 20
+#line 27
testRunner.When("I fetch the routes for the Areas controller\'s RouteBeginsWithAreaName action");
-#line 21
+#line 28
testRunner.Then("the route url is \"Area/Areas\"");
+#line 29
+ testRunner.When("I fetch the routes for the HttpAreas controller\'s RouteBeginsWithAreaName action");
+#line 30
+ testRunner.Then("the route url is \"ApiArea/ApiAreas\"");
#line hidden
this.ScenarioCleanup();
}
@@ -147,16 +165,22 @@ public virtual void GeneratingAreaRoutesWhenRouteUrlStartsWithTheAreaPrefix()
public virtual void GeneratingAreaRoutesWithAnExplicitAreaUrl()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Generating area routes with an explicit area url", ((string[])(null)));
-#line 23
+#line 32
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 24
+#line 33
testRunner.When("I fetch the routes for the ExplicitAreaUrl controller\'s Index action");
-#line 25
+#line 34
testRunner.Then("the route url is \"ExplicitArea/Index\"");
-#line 26
+#line 35
testRunner.And("the data token for \"area\" is \"Area\"");
+#line 36
+ testRunner.When("I fetch the routes for the HttpExplicitAreaUrl controller\'s Get action");
+#line 37
+ testRunner.Then("the route url is \"ApiExplicitArea/Get\"");
+#line 38
+ testRunner.And("the data token for \"area\" is \"ApiArea\"");
#line hidden
this.ScenarioCleanup();
}
@@ -168,16 +192,23 @@ public virtual void GeneratingAreaRoutesWithAnExplicitAreaUrlWhenRouteUrlsSpecif
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Generating area routes with an explicit area url when route urls specify a duplic" +
"ate area prefix", ((string[])(null)));
-#line 28
+#line 40
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 29
+#line 41
testRunner.When("I fetch the routes for the ExplicitAreaUrl controller\'s DuplicatePrefix action");
-#line 30
+#line 42
testRunner.Then("the route url is \"ExplicitArea/DuplicatePrefix\"");
-#line 31
+#line 43
testRunner.And("the data token for \"area\" is \"Area\"");
+#line 44
+ testRunner.When("I fetch the routes for the HttpExplicitAreaUrl controller\'s DuplicatePrefix actio" +
+ "n");
+#line 45
+ testRunner.Then("the route url is \"ApiExplicitArea/DuplicatePrefix\"");
+#line 46
+ testRunner.And("the data token for \"area\" is \"ApiArea\"");
#line hidden
this.ScenarioCleanup();
}
View
6 src/AttributeRouting.Specs/Features/RouteConstraints.feature
@@ -5,10 +5,12 @@ Background:
Scenario: Regex route constraints specified with an attribute
When I fetch the routes for the RouteConstraints controller's Index action
+ And I fetch the routes for the ApiRouteConstraints controller's Get action
Then the parameter "p1" is constrained by the pattern "\d+"
Scenario: Regex route constraints specified inline
When I fetch the routes for the RouteConstraints controller's InlineConstraints action
+ And I fetch the routes for the ApiRouteConstraints controller's InlineConstraints action
Then the route url is "InlineConstraints/{number}/{word}/{alphanum}/{capture}"
Then the parameter "number" is constrained by the pattern "\d+"
Then the parameter "word" is constrained by the pattern "\w{2}"
@@ -17,6 +19,8 @@ Scenario: Regex route constraints specified inline
Scenario: Multiple routes with different constraints
When I fetch the routes for the RouteConstraints controller's MultipleRoutes action
+ And I fetch the routes for the ApiRouteConstraints controller's MultipleRoutes action
Then the route named "MultipleConstraints1" has a constraint on "p1" of "\d+"
And the route named "MultipleConstraints2" has a constraint on "p1" of "\d{4}"
-
+ And the route named "ApiMultipleConstraints1" has a constraint on "p1" of "\d+"
+ And the route named "ApiMultipleConstraints2" has a constraint on "p1" of "\d{4}"
View
34 src/AttributeRouting.Specs/Features/RouteConstraints.feature.cs
@@ -84,6 +84,8 @@ public virtual void RegexRouteConstraintsSpecifiedWithAnAttribute()
#line 7
testRunner.When("I fetch the routes for the RouteConstraints controller\'s Index action");
#line 8
+ testRunner.And("I fetch the routes for the ApiRouteConstraints controller\'s Get action");
+#line 9
testRunner.Then("the parameter \"p1\" is constrained by the pattern \"\\d+\"");
#line hidden
this.ScenarioCleanup();
@@ -94,22 +96,25 @@ public virtual void RegexRouteConstraintsSpecifiedWithAnAttribute()
public virtual void RegexRouteConstraintsSpecifiedInline()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Regex route constraints specified inline", ((string[])(null)));
-#line 10
+#line 11
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 11
+#line 12
testRunner.When("I fetch the routes for the RouteConstraints controller\'s InlineConstraints action" +
"");
-#line 12
- testRunner.Then("the route url is \"InlineConstraints/{number}/{word}/{alphanum}/{capture}\"");
#line 13
- testRunner.Then("the parameter \"number\" is constrained by the pattern \"\\d+\"");
+ testRunner.And("I fetch the routes for the ApiRouteConstraints controller\'s InlineConstraints act" +
+ "ion");
#line 14
- testRunner.Then("the parameter \"word\" is constrained by the pattern \"\\w{2}\"");
+ testRunner.Then("the route url is \"InlineConstraints/{number}/{word}/{alphanum}/{capture}\"");
#line 15
- testRunner.Then("the parameter \"alphanum\" is constrained by the pattern \"[A-Za-z0-9]*\"");
+ testRunner.Then("the parameter \"number\" is constrained by the pattern \"\\d+\"");
#line 16
+ testRunner.Then("the parameter \"word\" is constrained by the pattern \"\\w{2}\"");
+#line 17
+ testRunner.Then("the parameter \"alphanum\" is constrained by the pattern \"[A-Za-z0-9]*\"");
+#line 18
testRunner.Then("the parameter \"capture\" is constrained by the pattern \"(gotcha)\"");
#line hidden
this.ScenarioCleanup();
@@ -120,16 +125,23 @@ public virtual void RegexRouteConstraintsSpecifiedInline()
public virtual void MultipleRoutesWithDifferentConstraints()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Multiple routes with different constraints", ((string[])(null)));
-#line 18
+#line 20
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 19
+#line 21
testRunner.When("I fetch the routes for the RouteConstraints controller\'s MultipleRoutes action");
-#line 20
+#line 22
+ testRunner.And("I fetch the routes for the ApiRouteConstraints controller\'s MultipleRoutes action" +
+ "");
+#line 23
testRunner.Then("the route named \"MultipleConstraints1\" has a constraint on \"p1\" of \"\\d+\"");
-#line 21
+#line 24
testRunner.And("the route named \"MultipleConstraints2\" has a constraint on \"p1\" of \"\\d{4}\"");
+#line 25
+ testRunner.And("the route named \"ApiMultipleConstraints1\" has a constraint on \"p1\" of \"\\d+\"");
+#line 26
+ testRunner.And("the route named \"ApiMultipleConstraints2\" has a constraint on \"p1\" of \"\\d{4}\"");
#line hidden
this.ScenarioCleanup();
}
View
44 src/AttributeRouting.Specs/Features/RouteConventions.feature
@@ -38,7 +38,39 @@ Scenario Outline: Generating routes using the RestfulRouteConvention on controll
| Edit | GET | Prefix/{id}/Edit |
| Update | PUT | Prefix/{id} |
| Delete | GET | Prefix/{id}/Delete |
- | Destroy | DELETE | Prefix/{id} |
+ | Destroy | DELETE | Prefix/{id} |
+
+Scenario Outline: Generating routes using the DefaultHttpRouteConvention
+ When I fetch the routes for the DefaultHttpRouteConvention controller's <action> action
+ Then the route url is "<url>"
+ And the default for "controller" is "DefaultHttpRouteConvention"
+ And the default for "action" is "<action>"
+ And the route for <action> is constrained to <method> requests
+
+ Examples:
+ | action | method | url |
+ | GetAll | GET | DefaultHttpRouteConvention |
+ | Get | GET | DefaultHttpRouteConvention/{id} |
+ | Post | POST | DefaultHttpRouteConvention |
+ | Put | PUT | DefaultHttpRouteConvention/{id} |
+ | Delete | DELETE | DefaultHttpRouteConvention/{id} |
+ | Custom | GET | DefaultHttpRouteConvention/Custom |
+
+Scenario Outline: Generating routes using the DefaultHttpRouteConventionPrefix on controllers with a RoutePrefix attribute
+ When I fetch the routes for the DefaultHttpRouteConventionPrefix controller's <action> action
+ Then the route url is "<url>"
+ And the default for "controller" is "DefaultHttpRouteConventionPrefix"
+ And the default for "action" is "<action>"
+ And the route for <action> is constrained to <method> requests
+
+ Examples:
+ | action | method | url |
+ | GetAll | GET | Prefix |
+ | Get | GET | Prefix/{id} |
+ | Post | POST | Prefix |
+ | Put | PUT | Prefix/{id} |
+ | Delete | DELETE | Prefix/{id} |
+ | Custom | GET | Prefix/Custom |
Scenario: Generating routes using the RestfulRouteConvention on actions with an explicit route defined
When I fetch the routes for the RestfulRouteConventionWithExplicitRoute controller's Index action
@@ -49,3 +81,13 @@ Scenario: Generating routes using the RestfulRouteConvention on actions with an
When I fetch the routes for the RestfulRouteConventionWithExplicitOrderedRoute controller's Index action
Then the 1st route url is "RestfulRouteConventionWithExplicitOrderedRoute/Primary"
And the 2nd route url is "RestfulRouteConventionWithExplicitOrderedRoute"
+
+Scenario: Generating routes using the DefaultHttpRouteConvention on actions with an explicit route defined
+ When I fetch the routes for the DefaultHttpRouteConventionWithExplicitRoute controller's Get action
+ Then the 1st route url is "DefaultHttpRouteConventionWithExplicitRoute"
+ And the 2nd route url is "Legacy"
+
+Scenario: Generating routes using the DefaultHttpRouteConvention on actions with an explicit ordered route defined
+ When I fetch the routes for the DefaultHttpRouteConventionWithExplicitOrderedRoute controller's Get action
+ Then the 1st route url is "DefaultHttpRouteConventionWithExplicitOrderedRoute/Primary"
+ And the 2nd route url is "DefaultHttpRouteConventionWithExplicitOrderedRoute"
View
122 src/AttributeRouting.Specs/Features/RouteConventions.feature.cs
@@ -138,22 +138,83 @@ public virtual void GeneratingRoutesUsingTheRestfulRouteConventionOnControllersW
}
[NUnit.Framework.TestAttribute()]
+ [NUnit.Framework.DescriptionAttribute("Generating routes using the DefaultHttpRouteConvention")]
+ [NUnit.Framework.TestCaseAttribute("GetAll", "GET", "DefaultHttpRouteConvention", new string[0])]
+ [NUnit.Framework.TestCaseAttribute("Get", "GET", "DefaultHttpRouteConvention/{id}", new string[0])]
+ [NUnit.Framework.TestCaseAttribute("Post", "POST", "DefaultHttpRouteConvention", new string[0])]
+ [NUnit.Framework.TestCaseAttribute("Put", "PUT", "DefaultHttpRouteConvention/{id}", new string[0])]
+ [NUnit.Framework.TestCaseAttribute("Delete", "DELETE", "DefaultHttpRouteConvention/{id}", new string[0])]
+ [NUnit.Framework.TestCaseAttribute("Custom", "GET", "DefaultHttpRouteConvention/Custom", new string[0])]
+ public virtual void GeneratingRoutesUsingTheDefaultHttpRouteConvention(string action, string method, string url, string[] exampleTags)
+ {
+ TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Generating routes using the DefaultHttpRouteConvention", exampleTags);
+#line 43
+this.ScenarioSetup(scenarioInfo);
+#line 3
+this.FeatureBackground();
+#line 44
+ testRunner.When(string.Format("I fetch the routes for the DefaultHttpRouteConvention controller\'s {0} action", action));
+#line 45
+ testRunner.Then(string.Format("the route url is \"{0}\"", url));
+#line 46
+ testRunner.And("the default for \"controller\" is \"DefaultHttpRouteConvention\"");
+#line 47
+ testRunner.And(string.Format("the default for \"action\" is \"{0}\"", action));
+#line 48
+ testRunner.And(string.Format("the route for {0} is constrained to {1} requests", action, method));
+#line hidden
+ this.ScenarioCleanup();
+ }
+
+ [NUnit.Framework.TestAttribute()]
+ [NUnit.Framework.DescriptionAttribute("Generating routes using the DefaultHttpRouteConventionPrefix on controllers with " +
+ "a RoutePrefix attribute")]
+ [NUnit.Framework.TestCaseAttribute("GetAll", "GET", "Prefix", new string[0])]
+ [NUnit.Framework.TestCaseAttribute("Get", "GET", "Prefix/{id}", new string[0])]
+ [NUnit.Framework.TestCaseAttribute("Post", "POST", "Prefix", new string[0])]
+ [NUnit.Framework.TestCaseAttribute("Put", "PUT", "Prefix/{id}", new string[0])]
+ [NUnit.Framework.TestCaseAttribute("Delete", "DELETE", "Prefix/{id}", new string[0])]
+ [NUnit.Framework.TestCaseAttribute("Custom", "GET", "Prefix/Custom", new string[0])]
+ public virtual void GeneratingRoutesUsingTheDefaultHttpRouteConventionPrefixOnControllersWithARoutePrefixAttribute(string action, string method, string url, string[] exampleTags)
+ {
+ TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Generating routes using the DefaultHttpRouteConventionPrefix on controllers with " +
+ "a RoutePrefix attribute", exampleTags);
+#line 59
+this.ScenarioSetup(scenarioInfo);
+#line 3
+this.FeatureBackground();
+#line 60
+ testRunner.When(string.Format("I fetch the routes for the DefaultHttpRouteConventionPrefix controller\'s {0} acti" +
+ "on", action));
+#line 61
+ testRunner.Then(string.Format("the route url is \"{0}\"", url));
+#line 62
+ testRunner.And("the default for \"controller\" is \"DefaultHttpRouteConventionPrefix\"");
+#line 63
+ testRunner.And(string.Format("the default for \"action\" is \"{0}\"", action));
+#line 64
+ testRunner.And(string.Format("the route for {0} is constrained to {1} requests", action, method));
+#line hidden
+ this.ScenarioCleanup();
+ }
+
+ [NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("Generating routes using the RestfulRouteConvention on actions with an explicit ro" +
"ute defined")]
public virtual void GeneratingRoutesUsingTheRestfulRouteConventionOnActionsWithAnExplicitRouteDefined()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Generating routes using the RestfulRouteConvention on actions with an explicit ro" +
"ute defined", ((string[])(null)));
-#line 43
+#line 75
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 44
+#line 76
testRunner.When("I fetch the routes for the RestfulRouteConventionWithExplicitRoute controller\'s I" +
"ndex action");
-#line 45
+#line 77
testRunner.Then("the 1st route url is \"RestfulRouteConventionWithExplicitRoute\"");
-#line 46
+#line 78
testRunner.And("the 2nd route url is \"Legacy\"");
#line hidden
this.ScenarioCleanup();
@@ -166,20 +227,65 @@ public virtual void GeneratingRoutesUsingTheRestfulRouteConventionOnActionsWithA
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Generating routes using the RestfulRouteConvention on actions with an explicit or" +
"dered route defined", ((string[])(null)));
-#line 48
+#line 80
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 49
+#line 81
testRunner.When("I fetch the routes for the RestfulRouteConventionWithExplicitOrderedRoute control" +
"ler\'s Index action");
-#line 50
+#line 82
testRunner.Then("the 1st route url is \"RestfulRouteConventionWithExplicitOrderedRoute/Primary\"");
-#line 51
+#line 83
testRunner.And("the 2nd route url is \"RestfulRouteConventionWithExplicitOrderedRoute\"");
#line hidden
this.ScenarioCleanup();
}
+
+ [NUnit.Framework.TestAttribute()]
+ [NUnit.Framework.DescriptionAttribute("Generating routes using the DefaultHttpRouteConvention on actions with an explici" +
+ "t route defined")]
+ public virtual void GeneratingRoutesUsingTheDefaultHttpRouteConventionOnActionsWithAnExplicitRouteDefined()
+ {
+ TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Generating routes using the DefaultHttpRouteConvention on actions with an explici" +
+ "t route defined", ((string[])(null)));
+#line 85
+this.ScenarioSetup(scenarioInfo);
+#line 3
+this.FeatureBackground();
+#line 86
+ testRunner.When("I fetch the routes for the DefaultHttpRouteConventionWithExplicitRoute controller" +
+ "\'s Get action");
+#line 87
+ testRunner.Then("the 1st route url is \"DefaultHttpRouteConventionWithExplicitRoute\"");
+#line 88
+ testRunner.And("the 2nd route url is \"Legacy\"");
+#line hidden
+ this.ScenarioCleanup();
+ }
+
+ [NUnit.Framework.TestAttribute()]
+ [NUnit.Framework.DescriptionAttribute("Generating routes using the DefaultHttpRouteConvention on actions with an explici" +
+ "t ordered route defined")]
+ public virtual void GeneratingRoutesUsingTheDefaultHttpRouteConventionOnActionsWithAnExplicitOrderedRouteDefined()
+ {
+ TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Generating routes using the DefaultHttpRouteConvention on actions with an explici" +
+ "t ordered route defined", ((string[])(null)));
+#line 90
+this.ScenarioSetup(scenarioInfo);
+#line 3
+this.FeatureBackground();
+#line 91
+ testRunner.When("I fetch the routes for the DefaultHttpRouteConventionWithExplicitOrderedRoute con" +
+ "troller\'s Get action");
+#line 92
+ testRunner.Then("the 1st route url is \"DefaultHttpRouteConventionWithExplicitOrderedRoute/Primary\"" +
+ "");
+#line 93
+ testRunner.And("the 2nd route url is \"DefaultHttpRouteConventionWithExplicitOrderedRoute\"");
+#line hidden
+ this.ScenarioCleanup();
+ }
}
}
#pragma warning restore
View
6 src/AttributeRouting.Specs/Features/RouteDefaults.feature
@@ -5,16 +5,19 @@ Background:
Scenario: Route default specified with an attribute
When I fetch the routes for the RouteDefaults controller's Index action
+ And I fetch the routes for the HttpRouteDefaults controller's Get action
Then the default for "p1" is "variable"
Scenario: Route default specified inline
When I fetch the routes for the RouteDefaults controller's InlineDefaults action
+ And I fetch the routes for the HttpRouteDefaults controller's InlineDefaults action
Then the route url is "InlineDefaults/{hello}/{goodnight}"
Then the default for "hello" is "sun"
Then the default for "goodnight" is "moon"
Scenario: Optional parameters specified with a url parameter token
When I fetch the routes for the RouteDefaults controller's Optionals action
+ And I fetch the routes for the HttpRouteDefaults controller's Optionals action
Then the route url is "Optionals/{p1}/{p2}/{p3}"
And the parameter "p1" is optional
And the parameter "p2" is optional
@@ -22,5 +25,8 @@ Scenario: Optional parameters specified with a url parameter token
Scenario: Multiple routes with different defaults
When I fetch the routes for the RouteDefaults controller's MultipleRoutes action
+ And I fetch the routes for the HttpRouteDefaults controller's MultipleRoutes action
Then the route named "MultipleDefaults1" has a default for "p1" of "first"
And the route named "MultipleDefaults2" has a default for "p1" of "second"
+ And the route named "ApiMultipleDefaults1" has a default for "p1" of "first"
+ And the route named "ApiMultipleDefaults2" has a default for "p1" of "second"
View
42 src/AttributeRouting.Specs/Features/RouteDefaults.feature.cs
@@ -84,6 +84,8 @@ public virtual void RouteDefaultSpecifiedWithAnAttribute()
#line 7
testRunner.When("I fetch the routes for the RouteDefaults controller\'s Index action");
#line 8
+ testRunner.And("I fetch the routes for the HttpRouteDefaults controller\'s Get action");
+#line 9
testRunner.Then("the default for \"p1\" is \"variable\"");
#line hidden
this.ScenarioCleanup();
@@ -94,17 +96,19 @@ public virtual void RouteDefaultSpecifiedWithAnAttribute()
public virtual void RouteDefaultSpecifiedInline()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Route default specified inline", ((string[])(null)));
-#line 10
+#line 11
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 11
- testRunner.When("I fetch the routes for the RouteDefaults controller\'s InlineDefaults action");
#line 12
- testRunner.Then("the route url is \"InlineDefaults/{hello}/{goodnight}\"");
+ testRunner.When("I fetch the routes for the RouteDefaults controller\'s InlineDefaults action");
#line 13
- testRunner.Then("the default for \"hello\" is \"sun\"");
+ testRunner.And("I fetch the routes for the HttpRouteDefaults controller\'s InlineDefaults action");
#line 14
+ testRunner.Then("the route url is \"InlineDefaults/{hello}/{goodnight}\"");
+#line 15
+ testRunner.Then("the default for \"hello\" is \"sun\"");
+#line 16
testRunner.Then("the default for \"goodnight\" is \"moon\"");
#line hidden
this.ScenarioCleanup();
@@ -115,19 +119,21 @@ public virtual void RouteDefaultSpecifiedInline()
public virtual void OptionalParametersSpecifiedWithAUrlParameterToken()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Optional parameters specified with a url parameter token", ((string[])(null)));
-#line 16
+#line 18
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 17
+#line 19
testRunner.When("I fetch the routes for the RouteDefaults controller\'s Optionals action");
-#line 18
+#line 20
+ testRunner.And("I fetch the routes for the HttpRouteDefaults controller\'s Optionals action");
+#line 21
testRunner.Then("the route url is \"Optionals/{p1}/{p2}/{p3}\"");
-#line 19
+#line 22
testRunner.And("the parameter \"p1\" is optional");
-#line 20
+#line 23
testRunner.And("the parameter \"p2\" is optional");
-#line 21
+#line 24
testRunner.And("the parameter \"p3\" is optional");
#line hidden
this.ScenarioCleanup();
@@ -138,16 +144,22 @@ public virtual void OptionalParametersSpecifiedWithAUrlParameterToken()
public virtual void MultipleRoutesWithDifferentDefaults()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Multiple routes with different defaults", ((string[])(null)));
-#line 23
+#line 26
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 24
+#line 27
testRunner.When("I fetch the routes for the RouteDefaults controller\'s MultipleRoutes action");
-#line 25
+#line 28
+ testRunner.And("I fetch the routes for the HttpRouteDefaults controller\'s MultipleRoutes action");
+#line 29
testRunner.Then("the route named \"MultipleDefaults1\" has a default for \"p1\" of \"first\"");
-#line 26
+#line 30
testRunner.And("the route named \"MultipleDefaults2\" has a default for \"p1\" of \"second\"");
+#line 31
+ testRunner.And("the route named \"ApiMultipleDefaults1\" has a default for \"p1\" of \"first\"");
+#line 32
+ testRunner.And("the route named \"ApiMultipleDefaults2\" has a default for \"p1\" of \"second\"");
#line hidden
this.ScenarioCleanup();
}
View
34 src/AttributeRouting.Specs/Features/RoutePrecedence.feature
@@ -31,4 +31,36 @@ Scenario: Route precedence among controllers added by base type using the config
And I add the routes from the RoutePrecedenceAmongControllers1 controller
When I generate the routes with this configuration
Then the routes from the RoutePrecedenceAmongDerivedControllers1 controller precede those from the RoutePrecedenceAmongControllers1 controller
- And the routes from the RoutePrecedenceAmongDerivedControllers2 controller precede those from the RoutePrecedenceAmongControllers1 controller
+ And the routes from the RoutePrecedenceAmongDerivedControllers2 controller precede those from the RoutePrecedenceAmongControllers1 controller
+
+# Web API
+
+Scenario: Web API route precedence among routes for an action using the Order property
+ When I fetch the routes for the HttpRoutePrecedenceAmongRoutes controller's Get action
+ Then 3 routes are found
+ And the 1st route's url is "Get/First"
+ And the 2nd route's url is "Get/Second"
+ And the 3rd route's url is "Get/Third"
+
+Scenario: Web API route precedence among actions within a controller using the Precedence property
+ When I fetch the routes for the HttpRoutePrecedenceAmongActions controller
+ Then the 1st route's url is "ApiRoute1"
+ And the 2nd route's url is "ApiRoute2"
+ And the 3rd route's url is "ApiRoute3"
+
+Scenario: Web API route precedence among controllers added individually using the configuration api
+ Given I have a new configuration object
+ And I add the routes from the HttpRoutePrecedenceAmongControllers1 controller
+ And I add the routes from the HttpRoutePrecedenceAmongControllers2 controller
+ And I add the routes from the HttpRoutePrecedenceAmongControllers3 controller
+ When I generate the routes with this configuration
+ Then the routes from the HttpRoutePrecedenceAmongControllers1 controller precede those from the HttpRoutePrecedenceAmongControllers2 controller
+ And the routes from the HttpRoutePrecedenceAmongControllers2 controller precede those from the HttpRoutePrecedenceAmongControllers3 controller
+
+Scenario: Web API route precedence among controllers added by base type using the configuration api
+ Given I have a new configuration object
+ And I add the routes from controllers derived from the HttpRoutePrecedenceAmongDerivedControllersBase controller
+ And I add the routes from the HttpRoutePrecedenceAmongControllers1 controller
+ When I generate the routes with this configuration
+ Then the routes from the HttpRoutePrecedenceAmongDerivedControllers1 controller precede those from the HttpRoutePrecedenceAmongControllers1 controller
+ And the routes from the HttpRoutePrecedenceAmongDerivedControllers2 controller precede those from the HttpRoutePrecedenceAmongControllers1 controller
View
108 src/AttributeRouting.Specs/Features/RoutePrecedence.feature.cs
@@ -176,6 +176,114 @@ public virtual void RoutePrecedenceAmongControllersAddedByBaseTypeUsingTheConfig
#line hidden
this.ScenarioCleanup();
}
+
+ [NUnit.Framework.TestAttribute()]
+ [NUnit.Framework.DescriptionAttribute("Web API route precedence among routes for an action using the Order property")]
+ public virtual void WebAPIRoutePrecedenceAmongRoutesForAnActionUsingTheOrderProperty()
+ {
+ TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Web API route precedence among routes for an action using the Order property", ((string[])(null)));
+#line 38
+this.ScenarioSetup(scenarioInfo);
+#line 3
+this.FeatureBackground();
+#line 39
+ testRunner.When("I fetch the routes for the HttpRoutePrecedenceAmongRoutes controller\'s Get action" +
+ "");
+#line 40
+ testRunner.Then("3 routes are found");
+#line 41
+ testRunner.And("the 1st route\'s url is \"Get/First\"");
+#line 42
+ testRunner.And("the 2nd route\'s url is \"Get/Second\"");
+#line 43
+ testRunner.And("the 3rd route\'s url is \"Get/Third\"");
+#line hidden
+ this.ScenarioCleanup();
+ }
+
+ [NUnit.Framework.TestAttribute()]
+ [NUnit.Framework.DescriptionAttribute("Web API route precedence among actions within a controller using the Precedence p" +
+ "roperty")]
+ public virtual void WebAPIRoutePrecedenceAmongActionsWithinAControllerUsingThePrecedenceProperty()
+ {
+ TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Web API route precedence among actions within a controller using the Precedence p" +
+ "roperty", ((string[])(null)));
+#line 45
+this.ScenarioSetup(scenarioInfo);
+#line 3
+this.FeatureBackground();
+#line 46
+ testRunner.When("I fetch the routes for the HttpRoutePrecedenceAmongActions controller");
+#line 47
+ testRunner.Then("the 1st route\'s url is \"ApiRoute1\"");
+#line 48
+ testRunner.And("the 2nd route\'s url is \"ApiRoute2\"");
+#line 49
+ testRunner.And("the 3rd route\'s url is \"ApiRoute3\"");
+#line hidden
+ this.ScenarioCleanup();
+ }
+
+ [NUnit.Framework.TestAttribute()]
+ [NUnit.Framework.DescriptionAttribute("Web API route precedence among controllers added individually using the configura" +
+ "tion api")]
+ public virtual void WebAPIRoutePrecedenceAmongControllersAddedIndividuallyUsingTheConfigurationApi()
+ {
+ TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Web API route precedence among controllers added individually using the configura" +
+ "tion api", ((string[])(null)));
+#line 51
+this.ScenarioSetup(scenarioInfo);
+#line 3
+this.FeatureBackground();
+#line 52
+ testRunner.Given("I have a new configuration object");
+#line 53
+ testRunner.And("I add the routes from the HttpRoutePrecedenceAmongControllers1 controller");
+#line 54
+ testRunner.And("I add the routes from the HttpRoutePrecedenceAmongControllers2 controller");
+#line 55
+ testRunner.And("I add the routes from the HttpRoutePrecedenceAmongControllers3 controller");
+#line 56
+ testRunner.When("I generate the routes with this configuration");
+#line 57
+ testRunner.Then("the routes from the HttpRoutePrecedenceAmongControllers1 controller precede those" +
+ " from the HttpRoutePrecedenceAmongControllers2 controller");
+#line 58
+ testRunner.And("the routes from the HttpRoutePrecedenceAmongControllers2 controller precede those" +
+ " from the HttpRoutePrecedenceAmongControllers3 controller");
+#line hidden
+ this.ScenarioCleanup();
+ }
+
+ [NUnit.Framework.TestAttribute()]
+ [NUnit.Framework.DescriptionAttribute("Web API route precedence among controllers added by base type using the configura" +
+ "tion api")]
+ public virtual void WebAPIRoutePrecedenceAmongControllersAddedByBaseTypeUsingTheConfigurationApi()
+ {
+ TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Web API route precedence among controllers added by base type using the configura" +
+ "tion api", ((string[])(null)));
+#line 60
+this.ScenarioSetup(scenarioInfo);
+#line 3
+this.FeatureBackground();
+#line 61
+ testRunner.Given("I have a new configuration object");
+#line 62
+ testRunner.And("I add the routes from controllers derived from the HttpRoutePrecedenceAmongDerive" +
+ "dControllersBase controller");
+#line 63
+ testRunner.And("I add the routes from the HttpRoutePrecedenceAmongControllers1 controller");
+#line 64
+ testRunner.When("I generate the routes with this configuration");
+#line 65
+ testRunner.Then("the routes from the HttpRoutePrecedenceAmongDerivedControllers1 controller preced" +
+ "e those from the HttpRoutePrecedenceAmongControllers1 controller");
+#line 66
+ testRunner.And("the routes from the HttpRoutePrecedenceAmongDerivedControllers2 controller preced" +
+ "e those from the HttpRoutePrecedenceAmongControllers1 controller");
+#line hidden
+ this.ScenarioCleanup();
+ }
}
}
#pragma warning restore
View
20 src/AttributeRouting.Specs/Features/StandardUsage.feature
@@ -19,4 +19,22 @@ Scenario Outline: Generating routes for an action method
| PUT | Update | Update/{id} |
| DELETE | Destroy | Destroy/{id} |
| GET | Wildcards | Wildcards/{*pathInfo} |
- | | AnyVerb | AnyVerb |
+ | | AnyVerb | AnyVerb |
+
+Scenario Outline: Generating routes for an API controller
+ When I fetch the routes for the HttpStandardUsage controller's <action> action
+ Then the route is constrained to <method> requests
+ And the route url is "<url>"
+ And the default for "controller" is "HttpStandardUsage"
+ And the default for "action" is "<action>"
+ And the namespace is "AttributeRouting.Specs.Subjects.Http"
+
+ Examples:
+ | method | action | url |
+ | GET | Get | api |
+ | HEAD | Get | api |
+ | POST | Post | api |
+ | PUT | Put | api/{id} |
+ | DELETE | Delete | api/{id} |
+ | GET | Wildcards | api/Wildcards/{*pathInfo} |
+ | | AnyVerb | api/AnyVerb |
View
32 src/AttributeRouting.Specs/Features/StandardUsage.feature.cs
@@ -103,6 +103,38 @@ public virtual void GeneratingRoutesForAnActionMethod(string method, string acti
#line hidden
this.ScenarioCleanup();
}
+
+ [NUnit.Framework.TestAttribute()]
+ [NUnit.Framework.DescriptionAttribute("Generating routes for an API controller")]
+ [NUnit.Framework.TestCaseAttribute("GET", "Get", "api", new string[0])]
+ [NUnit.Framework.TestCaseAttribute("HEAD", "Get", "api", new string[0])]
+ [NUnit.Framework.TestCaseAttribute("POST", "Post", "api", new string[0])]
+ [NUnit.Framework.TestCaseAttribute("PUT", "Put", "api/{id}", new string[0])]
+ [NUnit.Framework.TestCaseAttribute("DELETE", "Delete", "api/{id}", new string[0])]
+ [NUnit.Framework.TestCaseAttribute("GET", "Wildcards", "api/Wildcards/{*pathInfo}", new string[0])]
+ [NUnit.Framework.TestCaseAttribute("", "AnyVerb", "api/AnyVerb", new string[0])]
+ public virtual void GeneratingRoutesForAnAPIController(string method, string action, string url, string[] exampleTags)
+ {
+ TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Generating routes for an API controller", exampleTags);
+#line 24
+this.ScenarioSetup(scenarioInfo);
+#line 3
+this.FeatureBackground();
+#line 25
+ testRunner.When(string.Format("I fetch the routes for the HttpStandardUsage controller\'s {0} action", action));
+#line 26
+ testRunner.Then(string.Format("the route is constrained to {0} requests", method));
+#line 27
+ testRunner.And(string.Format("the route url is \"{0}\"", url));
+#line 28
+ testRunner.And("the default for \"controller\" is \"HttpStandardUsage\"");
+#line 29
+ testRunner.And(string.Format("the default for \"action\" is \"{0}\"", action));
+#line 30
+ testRunner.And("the namespace is \"AttributeRouting.Specs.Subjects.Http\"");
+#line hidden
+ this.ScenarioCleanup();
+ }
}
}
#pragma warning restore
View
17 src/AttributeRouting.Specs/ScenarioContextExtensions.cs
@@ -1,5 +1,7 @@
using System.Collections.Generic;
+using System.Linq;
using System.Web.Routing;
+using AttributeRouting.Framework;
using TechTalk.SpecFlow;
namespace AttributeRouting.Specs
@@ -15,5 +17,20 @@ public static IEnumerable<Route> GetFetchedRoutes(this ScenarioContext context)
{
return context.Get<IEnumerable<Route>>("FetchedRoutes");
}
+
+ public static IEnumerable<Web.Mvc.Framework.AttributeRoute> GetFetchedMvcRoutes(this ScenarioContext context) {
+ return context.GetFetchedRoutes().OfType<Web.Mvc.Framework.AttributeRoute>();
+ }
+
+ public static IEnumerable<Web.Http.WebHost.Framework.AttributeRoute> GetFetchedHttpWebHostRoutes(this ScenarioContext context) {
+ return context.GetFetchedRoutes().OfType<Web.Http.WebHost.Framework.AttributeRoute>();
+ }
+
+ public static IEnumerable<IAttributeRouteContainer> GetFetchedRouteContainers(this ScenarioContext context) {
+ IEnumerable<IAttributeRouteContainer> mvcRoutes = context.GetFetchedMvcRoutes().Select(r => r.Container);
+ IEnumerable<IAttributeRouteContainer> webRoutes = context.GetFetchedHttpWebHostRoutes().Select(r => r.Container);
+
+ return mvcRoutes.Union(webRoutes);
+ }
}
}
View
3  src/AttributeRouting.Specs/Steps/LoggingSteps.cs
@@ -4,7 +4,6 @@
using System.Text;
using System.Web.Routing;
using AttributeRouting.Web.Logging;
-using AttributeRouting.Web.Mvc.Framework;
using NUnit.Framework;
using TechTalk.SpecFlow;
@@ -16,7 +15,7 @@ public class LoggingDefinitions
[When(@"I log the routes")]
public void WhenILogTheRoutes()
{
- RouteTable.Routes.Cast<AttributeRoute>().LogTo(Console.Out);
+ RouteTable.Routes.Cast<Route>().LogTo(Console.Out);
}
[Then(@"ta-da!")]
View
29 src/AttributeRouting.Specs/Steps/RouteConstraintSteps.cs
@@ -1,7 +1,5 @@
using System.Linq;
-using AttributeRouting.Framework;
using AttributeRouting.Web;
-using AttributeRouting.Web.Mvc.Framework;
using NUnit.Framework;
using TechTalk.SpecFlow;
@@ -13,25 +11,28 @@ public class RouteConstraintSteps
[Then(@"the parameter ""(.*?)"" is constrained by the pattern ""(.*?)""")]
public void ThenTheParameterIsContrainedBy(string key, object pattern)
{
- var route = ScenarioContext.Current.GetFetchedRoutes().First();
+ var routes = ScenarioContext.Current.GetFetchedRouteContainers();
- Assert.That(route, Is.Not.Null);
- Assert.That(route.Constraints[key], Is.TypeOf(typeof(RegexRouteConstraint)));
- Assert.That(((RegexRouteConstraint)route.Constraints[key]).Pattern, Is.EqualTo(pattern));
+ foreach (var route in routes) {
+ Assert.That(route, Is.Not.Null);
+ Assert.That(route.Constraints[key], Is.TypeOf(typeof (RegexRouteConstraint)));
+ Assert.That(((RegexRouteConstraint) route.Constraints[key]).Pattern, Is.EqualTo(pattern));
+ }
}
[Then(@"the route named ""(.*)"" has a constraint on ""(.*)"" of ""(.*)""")]
- public void ThenTheRouteNamedHasAConstraintOnOf(string routeName, string key, string value)
- {
- var route = ScenarioContext.Current.GetFetchedRoutes().Cast<AttributeRoute>().SingleOrDefault(r => r.Container.RouteName == routeName);
+ public void ThenTheRouteNamedHasAConstraintOnOf(string routeName, string key, string value) {
+ var routes = ScenarioContext.Current.GetFetchedRouteContainers().Where(r => r.RouteName == routeName);
- Assert.That(route, Is.Not.Null);
+ foreach (var route in routes) {
+ Assert.That(route, Is.Not.Null);
- var constraint = route.Constraints[key];
+ var constraint = route.Constraints[key];
- Assert.That(constraint, Is.Not.Null);
- Assert.That(constraint, Is.TypeOf(typeof(RegexRouteConstraint)));
- Assert.That(((RegexRouteConstraint)route.Constraints[key]).Pattern, Is.EqualTo(value));
+ Assert.That(constraint, Is.Not.Null);
+ Assert.That(constraint, Is.TypeOf(typeof (RegexRouteConstraint)));
+ Assert.That(((RegexRouteConstraint) route.Constraints[key]).Pattern, Is.EqualTo(value));
+ }
}
}
}
View
21 src/AttributeRouting.Specs/Steps/RouteDefaultsSteps.cs
@@ -1,4 +1,5 @@
using System.Linq;
+using System.Web.Http;
using System.Web.Mvc;
using AttributeRouting.Framework;
using AttributeRouting.Web.Mvc.Framework;
@@ -13,23 +14,27 @@ public class RouteDefaultsSteps
[Then(@"the parameter ""(.*?)"" is optional")]
public void ThenTheParameterIsOptional(string name)
{
- var route = ScenarioContext.Current.GetFetchedRoutes().First();
+ var routes = ScenarioContext.Current.GetFetchedRoutes();
- Assert.That(route, Is.Not.Null);
- Assert.That(route.Defaults[name], Is.EqualTo(UrlParameter.Optional));
+ foreach (var route in routes) {
+ Assert.That(route, Is.Not.Null);
+ Assert.That(route.Defaults[name], Is.EqualTo(UrlParameter.Optional).Or.EqualTo(RouteParameter.Optional));
+ }
}
[Then(@"the route named ""(.*)"" has a default for ""(.*)"" of ""?(.*?)""?")]
public void ThenTheRouteNamedHasADefaultForOf(string routeName, string key, string value)
{
- var route = ScenarioContext.Current.GetFetchedRoutes().Cast<AttributeRoute>().SingleOrDefault(r => r.Container.RouteName == routeName);
+ var routes = ScenarioContext.Current.GetFetchedRouteContainers().Where(c => c.RouteName == routeName);
- Assert.That(route, Is.Not.Null);
+ foreach (var route in routes) {
+ Assert.That(route, Is.Not.Null);
- var routeDefault = route.Defaults[key];
+ var routeDefault = route.Defaults[key];
- Assert.That(routeDefault, Is.Not.Null);
- Assert.That(routeDefault.ToString(), Is.EqualTo(value));
+ Assert.That(routeDefault, Is.Not.Null);
+ Assert.That(routeDefault.ToString(), Is.EqualTo(value));
+ }
}
}
}
View
13 src/AttributeRouting.Specs/Steps/RoutePrecedenceSteps.cs
@@ -3,6 +3,7 @@
using System.Linq;
using System.Text;
using System.Web.Routing;
+using AttributeRouting.Web.Http.WebHost;
using AttributeRouting.Web.Mvc;
using NUnit.Framework;
using TechTalk.SpecFlow;
@@ -13,11 +14,13 @@ namespace AttributeRouting.Specs.Steps
public class RoutePrecedenceSteps
{
private AttributeRoutingConfiguration _configuration;
+ private HttpAttributeRoutingConfiguration _httpConfiguration;
[Given(@"I have a new configuration object")]
public void GivenIHaveANewConfigurationObject()
{
_configuration = new AttributeRoutingConfiguration();
+ _httpConfiguration = new HttpAttributeRoutingConfiguration();
}
[Given(@"I add the routes from the (.*) controller")]
@@ -25,6 +28,9 @@ public void GivenIAddTheRoutesFromTheController(string controllerName)
{
var controllerType = GetControllerType(controllerName);
_configuration.AddRoutesFromController(controllerType);
+
+ if (controllerName.StartsWith("Http"))
+ _httpConfiguration.AddRoutesFromController(controllerType);
}
[Given(@"I add the routes from controllers derived from the (.*) controller")]
@@ -32,6 +38,9 @@ public void GivenIAddTheRoutesFromControllersOfTypeBaseController(string baseCon
{
var baseControllerType = GetControllerType(baseControllerName);
_configuration.AddRoutesFromControllersOfType(baseControllerType);
+
+ if (baseControllerName.StartsWith("Http"))
+ _httpConfiguration.AddRoutesFromControllersOfType(baseControllerType);
}
[When(@"I generate the routes with this configuration")]
@@ -39,6 +48,7 @@ public void WhenIGenerateTheRoutesWithThisConfiguration()
{
RouteTable.Routes.Clear();
RouteTable.Routes.MapAttributeRoutes(_configuration);
+ RouteTable.Routes.MapHttpAttributeRoutes(_httpConfiguration);
}
[Then(@"the routes from the (.*) controller precede those from the (.*) controller")]
@@ -58,6 +68,9 @@ public void ThenTheRoutesFromTheFirstControllerPrecedeThoseFromTheNextController
private Type GetControllerType(string controllerName)
{
+ if (controllerName.StartsWith("Http"))
+ controllerName = "Http." + controllerName;
+
var typeName = String.Format("AttributeRouting.Specs.Subjects.{0}Controller, AttributeRouting.Specs",
controllerName);
View
2  src/AttributeRouting.Specs/Steps/SharedSteps.cs
@@ -1,5 +1,6 @@
using System.Linq;
using System.Web.Routing;
+using AttributeRouting.Web.Http.WebHost;
using AttributeRouting.Web.Mvc;
using NUnit.Framework;
using TechTalk.SpecFlow;
@@ -14,6 +15,7 @@ public void GivenIGenerateTheRoutesDefinedInTheSubjectControllers()
{
RouteTable.Routes.Clear();
RouteTable.Routes.MapAttributeRoutes();
+ RouteTable.Routes.MapHttpAttributeRoutes();
}
[When(@"I fetch the routes for the (.*?) controller's (.*?) action")]
View
49 src/AttributeRouting.Specs/Subjects/Http/RouteAreasControllers.cs
@@ -0,0 +1,49 @@
+using System.Web.Http;
+using AttributeRouting.Web.Http;
+
+namespace AttributeRouting.Specs.Subjects.Http
+{
+ [RouteArea("ApiArea")]
+ public class HttpAreasController : ApiController
+ {
+ [GET("Get")]
+ public string Get()
+ {
+ return "";
+ }
+
+ [GET("ApiArea/DuplicatePrefix")]
+ public string DuplicatePrefix()
+ {
+ return "";
+ }
+
+ [GET("ApiAreaAbsolute", IsAbsoluteUrl = true)]
+ public string Absolute()
+ {
+ return "";
+ }
+
+ [GET("ApiAreas")]
+ public string RouteBeginsWithAreaName()
+ {
+ return "";
+ }
+ }
+
+ [RouteArea("ApiArea", AreaUrl = "ApiExplicitArea")]
+ public class HttpExplicitAreaUrlController : ApiController
+ {
+ [GET("Get")]
+ public string Get()
+ {
+ return "";
+ }
+
+ [GET("ApiExplicitArea/DuplicatePrefix")]
+ public string DuplicatePrefix()
+ {
+ return "";
+ }
+ }
+}
View
31 src/AttributeRouting.Specs/Subjects/Http/RouteConstraintsController.cs
@@ -0,0 +1,31 @@
+using System.Web.Http;
+using AttributeRouting.Web;
+using AttributeRouting.Web.Http;
+
+namespace AttributeRouting.Specs.Subjects.Http
+{
+ public class ApiRouteConstraintsController : ApiController
+ {
+ [GET("Constraint/{p1}")]
+ [RegexRouteConstraint("p1", @"\d+")]
+ public string Get()
+ {
+ return "";
+ }
+
+ [GET(@"InlineConstraints/{number(\d+)}/{word(\w{2})}/{alphanum([A-Za-z0-9]*)}/{capture((gotcha))}")]
+ public string InlineConstraints(long number, string word)
+ {
+ return "";
+ }
+
+ [GET("MultipleConstraints/1/{p1}", RouteName = "ApiMultipleConstraints1")]
+ [GET("MultipleConstraints/2/{p1}", RouteName = "ApiMultipleConstraints2")]
+ [RegexRouteConstraint("p1", @"\d+", ForRouteNamed = "ApiMultipleConstraints1")]
+ [RegexRouteConstraint("p1", @"\d{4}", ForRouteNamed = "ApiMultipleConstraints2")]
+ public string MultipleRoutes()
+ {
+ return "";
+ }
+ }
+}
View
84 src/AttributeRouting.Specs/Subjects/Http/RouteConventionsController.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Web.Http;
+using AttributeRouting.Web.Http;
+
+namespace AttributeRouting.Specs.Subjects.Http {
+
+ [DefaultHttpRouteConvention]
+ public class DefaultHttpRouteConventionController : ApiController {
+
+ public string GetAll() {
+ return "";
+ }
+
+ public string Get(int id) {
+ return "";
+ }
+
+ public string Post() {
+ return "";
+ }
+
+ public string Delete(int id) {
+ return "";
+ }
+
+ public string Put(int id) {
+ return "";
+ }
+
+ [GET("Custom")]
+ public string Custom() {
+ return "";
+ }
+ }
+
+ [DefaultHttpRouteConvention]
+ [RoutePrefix("Prefix")]
+ public class DefaultHttpRouteConventionPrefixController : ApiController {
+
+ public string GetAll() {
+ return "";
+ }
+
+ public string Get(int id) {
+ return "";
+ }
+
+ public string Post() {
+ return "";
+ }
+
+ public string Delete(int id) {
+ return "";
+ }
+
+ public string Put(int id) {
+ return "";
+ }
+
+ [GET("Custom")]
+ public string Custom() {
+ return "";
+ }
+ }
+
+ [DefaultHttpRouteConvention]
+ public class DefaultHttpRouteConventionWithExplicitRouteController : ApiController {
+ [GET("Legacy", IsAbsoluteUrl = true)]
+ public string Get() {
+ return "";
+ }
+ }
+
+ [DefaultHttpRouteConvention]
+ public class DefaultHttpRouteConventionWithExplicitOrderedRouteController : ApiController {
+ [GET("Primary", Order = 1)]
+ public string Get() {
+ return "";
+ }
+ }
+}
View
36 src/AttributeRouting.Specs/Subjects/Http/RouteDefaultsController.cs
@@ -0,0 +1,36 @@
+using System.Web.Http;
+using AttributeRouting.Web.Http;
+
+namespace AttributeRouting.Specs.Subjects.Http
+{
+ public class HttpRouteDefaultsController : ApiController
+ {
+ [GET("Default/{p1}")]
+ [RouteDefault("p1", "variable")]
+ public string Get()
+ {
+ return "";
+ }
+
+ [GET("InlineDefaults/{hello=sun}/{goodnight=moon}")]
+ public string InlineDefaults()
+ {
+ return "";
+ }
+
+ [GET("Optionals/{p1?}/{?p2}/{?p3?}")]
+ public string Optionals(string p1, string p2, string p3)
+ {
+ return "";
+ }
+
+ [GET("MultipleDefaults/1/{p1}", RouteName = "ApiMultipleDefaults1")]
+ [GET("MultipleDefaults/2/{p1}", RouteName = "ApiMultipleDefaults2")]
+ [RouteDefault("p1", "first", ForRouteNamed = "ApiMultipleDefaults1")]
+ [RouteDefault("p1", "second", ForRouteNamed = "ApiMultipleDefaults2")]
+ public string MultipleRoutes()
+ {
+ return "";
+ }
+ }
+}
View
87 src/AttributeRouting.Specs/Subjects/Http/RoutePrecedenceController.cs
@@ -0,0 +1,87 @@
+using System.Web.Http;
+using AttributeRouting.Web.Http;
+
+namespace AttributeRouting.Specs.Subjects.Http
+{
+ public class HttpRoutePrecedenceAmongRoutesController : ApiController
+ {
+ [GET("Get/Second", Order = 2)]
+ [GET("Get/Third", Order = 3)]
+ [GET("Get/First", Order = 1)]
+ public string Get()
+ {
+ return "";
+ }
+ }
+
+ public partial class HttpRoutePrecedenceAmongActionsController : ApiController
+ {
+ [GET("ApiRoute1", Precedence = 1)]
+ public string Route1()
+ {
+ return "";
+ }
+
+ [GET("ApiRoute3")]
+ public string Route3()
+ {
+ return "";
+ }
+ }
+
+ public partial class HttpRoutePrecedenceAmongActionsController
+ {
+ [GET("ApiRoute2", Precedence = 2)]
+ public string Route2()
+ {
+ return "";
+ }
+ }
+
+ public class HttpRoutePrecedenceAmongControllers3Controller : ApiController
+ {
+ [GET("ApiController3/Get")]
+ public string Get()
+ {
+ return "";
+ }
+ }
+
+ public class HttpRoutePrecedenceAmongControllers1Controller : ApiController
+ {
+ [GET("ApiController1/Get")]
+ public string Get()
+ {
+ return "";
+ }
+ }
+
+ public class HttpRoutePrecedenceAmongControllers2Controller : ApiController
+ {
+ [GET("ApiController2/Get")]
+ public string Get()
+ {
+ return "";
+ }
+ }
+
+ public abstract class HttpRoutePrecedenceAmongDerivedControllersBaseController : ApiController { }
+
+ public class HttpRoutePrecedenceAmongDerivedControllers1 : HttpRoutePrecedenceAmongDerivedControllersBaseController
+ {
+ [GET("ApiDerivedController1/Get")]
+ public string Get()
+ {
+ return "";
+ }
+ }
+
+ public class HttpRoutePrecedenceAmongDerivedControllers2 : HttpRoutePrecedenceAmongDerivedControllersBaseController
+ {
+ [GET("ApiDerivedController2/Get")]
+ public string Get()
+ {
+ return "";
+ }
+ }
+}
View
45 src/AttributeRouting.Specs/Subjects/Http/StandardUsageController.cs
@@ -0,0 +1,45 @@
+using System.Web.Http;
+using System.Web.Mvc;
+using AttributeRouting.Web.Http;
+
+namespace AttributeRouting.Specs.Subjects.Http
+{
+ public class HttpStandardUsageController : ApiController
+ {
+ [GET("api")]
+ public string Get()
+ {
+ return "";
+ }
+
+ [POST("api")]
+ public string Post()
+ {
+ return "";
+ }
+
+ [PUT("api/{id}")]
+ public string Put()
+ {
+ return "";
+ }
+
+ [DELETE("api/{id}")]
+ public string Delete()
+ {
+ return "";
+ }
+
+ [GET("api/Wildcards/{*pathInfo}")]
+ public string Wildcards()
+ {
+ return "";
+ }
+
+ [HttpRoute("api/AnyVerb")]
+ public string AnyVerb()
+ {
+ return "";
+ }
+ }
+}
View
19 src/AttributeRouting.Specs/packages.config
@@ -1,8 +1,13 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
- <package id="Moq" version="3.1.416.3" />
- <package id="MvcContrib.Mvc3.TestHelper-ci" version="3.0.91.0" />
- <package id="NUnit" version="2.5.7.10213" />
- <package id="RhinoMocks" version="3.6" />
- <package id="SpecFlow" version="1.8.1" />
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="AspNetWebApi.Core" version="4.0.20126.16343" />
+ <package id="Moq" version="3.1.416.3" />
+ <package id="MvcContrib.Mvc3.TestHelper-ci" version="3.0.91.0" />
+ <package id="NUnit" version="2.5.7.10213" />
+ <package id="RhinoMocks" version="3.6" />
+ <package id="SpecFlow" version="1.8.1" />
+ <package id="System.Json" version="4.0.20126.16343" />
+ <package id="System.Net.Http" version="2.0.20126.16343" />
+ <package id="System.Net.Http.Formatting" version="4.0.20126.16343" />
+ <package id="System.Web.Http.Common" version="4.0.20126.16343" />
</packages>
View
16 src/AttributeRouting.Web.Http.SelfHost/Framework/AttributeRouteContainer.cs
@@ -36,5 +36,21 @@ public class AttributeRouteContainer : AttributeRouteContainerBase<AttributeRout
get { return Route.DataTokens; }
set { throw new NotImplementedException("WebAPI HttpRoute.DataTokens has no setter."); }
}
+
+ /// <summary>
+ /// Constraints dictionary
+ /// </summary>
+ public override IDictionary<string, object> Constraints {
+ get { return Route.Constraints; }
+ set { throw new NotImplementedException("WebAPI HttpRoute.Constraints has no setter."); }
+ }
+
+ /// <summary>
+ /// Defaults dictionary
+ /// </summary>
+ public override IDictionary<string, object> Defaults {
+ get { return Route.Defaults; }
+ set { throw new NotImplementedException("WebAPI HttpRoute.Constraints has no setter."); }
+ }
}
}
View
16 src/AttributeRouting.Web.Http.WebHost/Framework/AttributeRouteContainer.cs
@@ -33,5 +33,21 @@ public class AttributeRouteContainer : AttributeRouteContainerBase<AttributeRout
get { return Route.DataTokens; }
set { Route.DataTokens = new RouteValueDictionary(value); }
}
+
+ /// <summary>
+ /// Constraints dictionary
+ /// </summary>
+ public override IDictionary<string, object> Constraints {
+ get { return Route.Constraints; }
+ set { Route.Constraints = new RouteValueDictionary(value); }
+ }
+
+ /// <summary>
+ /// Defaults dictionary
+ /// </summary>
+ public override IDictionary<string, object> Defaults {
+ get { return Route.Defaults; }
+ set { Route.Defaults = new RouteValueDictionary(value); }
+ }
}
}
View
12 src/AttributeRouting.Web.Http/DefaultHttpRouteConventionAttribute.cs
@@ -17,10 +17,10 @@ public class DefaultHttpRouteConventionAttribute : HttpConventionAttribute
// Setup conventions
private static readonly List<HttpRouteConventionInfo> Conventions = new List<HttpRouteConventionInfo>
{
- // api/products (GET)
- new HttpRouteConventionInfo(HttpMethod.Get, ""),
// api/products/{id} (GET)
new HttpRouteConventionInfo(HttpMethod.Get, "{id}"),
+ // api/products (GET)
+ new HttpRouteConventionInfo(HttpMethod.Get, ""),
// api/products (POST)
new HttpRouteConventionInfo(HttpMethod.Post, ""),
// api/products/{id} (DELETE)
@@ -29,6 +29,8 @@ public class DefaultHttpRouteConventionAttribute : HttpConventionAttribute
new HttpRouteConventionInfo(HttpMethod.Put, "{id}")
};
+ private readonly List<HttpRouteConventionInfo> AlreadyUsed = new List<HttpRouteConventionInfo>();
+
public override IEnumerable<IRouteAttribute> GetRouteAttributes(MethodInfo actionMethod)
{
// Logic from ApiControllerActionSelector
@@ -51,14 +53,14 @@ public override IEnumerable<IRouteAttribute> GetRouteAttributes(MethodInfo actio
{
var requiresId = !string.IsNullOrEmpty(c.Url);
- if (!c.AlreadyUsed)
+ if (!AlreadyUsed.Contains(c))
{
// Check first parameter, if it requires ID
if (!requiresId || (actionMethod.GetParameters().Length > 0 && actionMethod.GetParameters()[0].Name.Equals("id", StringComparison.OrdinalIgnoreCase)))
{
yield return BuildRouteAttribute(c);
- c.AlreadyUsed = true;
+ AlreadyUsed.Add(c);
}
}
}
@@ -98,10 +100,8 @@ public HttpRouteConventionInfo(HttpMethod httpMethod, string url)
{
HttpMethod = httpMethod;
Url = url;
- AlreadyUsed = false;
}
- public bool AlreadyUsed { get; set; }
public HttpMethod HttpMethod { get; private set; }
public string Url { get; private set; }
}
View
16 src/AttributeRouting.Web.Mvc/Framework/AttributeRouteContainer.cs
@@ -32,5 +32,21 @@ public class AttributeRouteContainer : AttributeRouteContainerBase<AttributeRout
get { return Route.DataTokens; }
set { Route.DataTokens = new RouteValueDictionary(value); }
}
+
+ /// <summary>
+ /// Constraints dictionary
+ /// </summary>
+ public override IDictionary<string, object> Constraints {
+ get { return Route.Constraints; }
+ set { Route.Constraints = new RouteValueDictionary(value); }
+ }
+
+ /// <summary>
+ /// Defaults dictionary
+ /// </summary>
+ public override IDictionary<string, object> Defaults {
+ get { return Route.Defaults; }
+ set { Route.Defaults = new RouteValueDictionary(value); }
+ }
}
}
View
9 src/AttributeRouting/AttributeRoutingConfiguration.cs
@@ -124,10 +124,10 @@ public void ScanAssembly(Assembly assembly)
/// Adds all the routes for all the controllers that derive from the specified controller
/// to the end of the route collection.
/// </summary>
- /// <typeparam name="TController">The base controller type</typeparam>
- public void AddRoutesFromControllersOfType<TController>()
+ /// <typeparam name="T">The base controller type</typeparam>
+ public void AddRoutesFromControllersOfType<T>() where T:TController
{
- AddRoutesFromControllersOfType(typeof(TController));
+ AddRoutesFromControllersOfType(typeof(T));
}
/// <summary>
@@ -153,6 +153,9 @@ where baseControllerType.IsAssignableFrom(controllerType)
/// <param name="controllerType">The controller type</param>
public void AddRoutesFromController(Type controllerType)
{
+ if (!typeof(TController).IsAssignableFrom(controllerType))
+ return;
+
if (!PromotedControllerTypes.Contains(controllerType))
PromotedControllerTypes.Add(controllerType);
}
View
11 src/AttributeRouting/Framework/AttributeRouteContainerBase.cs
@@ -41,7 +41,16 @@ public abstract class AttributeRouteContainerBase<TRoute> : IAttributeRouteConta
/// <summary>
/// DataTokens dictionary
/// </summary>
- public abstract IDictionary<string, object> DataTokens { get; set; }
+ public abstract IDictionary<string, object> DataTokens { get; set; }
+ /// <summary>
+ /// Constraints dictionary
+ /// </summary>
+ public abstract IDictionary<string, object> Constraints { get; set; }
+
+ /// <summary>
+ /// Defaults dictionary
+ /// </summary>
+ public abstract IDictionary<string, object> Defaults { get; set; }
}
}
View
10 src/AttributeRouting/Framework/IAttributeRouteContainer.cs
@@ -31,5 +31,15 @@ public interface IAttributeRouteContainer {
/// DataTokens dictionary
/// </summary>
IDictionary<string, object> DataTokens { get; set; }
+
+ /// <summary>
+ /// Constraints dictionary
+ /// </summary>
+ IDictionary<string, object> Constraints { get; set; }
+
+ /// <summary>
+ /// Defaults dictionary
+ /// </summary>
+ IDictionary<string, object> Defaults { get; set; }
}
}

No commit comments for this range

Something went wrong with that request. Please try again.