Add extension methods for using routing with Middleware
This commit is contained in:
parent
cc501bc025
commit
cb39589864
|
|
@ -10,6 +10,7 @@
|
||||||
],
|
],
|
||||||
"packages": {
|
"packages": {
|
||||||
"Microsoft.AspNet.Routing.Abstractions": { },
|
"Microsoft.AspNet.Routing.Abstractions": { },
|
||||||
|
"Microsoft.AspNet.Routing.Extensions": { },
|
||||||
"Microsoft.AspNet.Routing": { }
|
"Microsoft.AspNet.Routing": { }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
30
Routing.sln
30
Routing.sln
|
|
@ -28,6 +28,10 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Routing.Ab
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.Routing.Abstractions.Tests", "test\Microsoft.AspNet.Mvc.Routing.Abstractions.Tests\Microsoft.AspNet.Mvc.Routing.Abstractions.Tests.xproj", "{741B0B05-CE96-473B-B962-6B0A347DF79A}"
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.Routing.Abstractions.Tests", "test\Microsoft.AspNet.Mvc.Routing.Abstractions.Tests\Microsoft.AspNet.Mvc.Routing.Abstractions.Tests.xproj", "{741B0B05-CE96-473B-B962-6B0A347DF79A}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Routing.Extensions", "src\Microsoft.AspNet.Routing.Extensions\Microsoft.AspNet.Routing.Extensions.xproj", "{579C3FD2-DFFA-4B64-BFC3-130C11F3568F}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Routing.Extensions.Tests", "test\Microsoft.AspNet.Routing.Extensions.Tests\Microsoft.AspNet.Routing.Extensions.Tests.xproj", "{FD0151B4-7153-49A8-9D90-62A252420230}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|
@ -116,6 +120,30 @@ Global
|
||||||
{741B0B05-CE96-473B-B962-6B0A347DF79A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
{741B0B05-CE96-473B-B962-6B0A347DF79A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
{741B0B05-CE96-473B-B962-6B0A347DF79A}.Release|x86.ActiveCfg = Release|Any CPU
|
{741B0B05-CE96-473B-B962-6B0A347DF79A}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{741B0B05-CE96-473B-B962-6B0A347DF79A}.Release|x86.Build.0 = Release|Any CPU
|
{741B0B05-CE96-473B-B962-6B0A347DF79A}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{579C3FD2-DFFA-4B64-BFC3-130C11F3568F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{579C3FD2-DFFA-4B64-BFC3-130C11F3568F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{579C3FD2-DFFA-4B64-BFC3-130C11F3568F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||||
|
{579C3FD2-DFFA-4B64-BFC3-130C11F3568F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||||
|
{579C3FD2-DFFA-4B64-BFC3-130C11F3568F}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{579C3FD2-DFFA-4B64-BFC3-130C11F3568F}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{579C3FD2-DFFA-4B64-BFC3-130C11F3568F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{579C3FD2-DFFA-4B64-BFC3-130C11F3568F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{579C3FD2-DFFA-4B64-BFC3-130C11F3568F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
|
{579C3FD2-DFFA-4B64-BFC3-130C11F3568F}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
|
{579C3FD2-DFFA-4B64-BFC3-130C11F3568F}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{579C3FD2-DFFA-4B64-BFC3-130C11F3568F}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{FD0151B4-7153-49A8-9D90-62A252420230}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{FD0151B4-7153-49A8-9D90-62A252420230}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{FD0151B4-7153-49A8-9D90-62A252420230}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||||
|
{FD0151B4-7153-49A8-9D90-62A252420230}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||||
|
{FD0151B4-7153-49A8-9D90-62A252420230}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{FD0151B4-7153-49A8-9D90-62A252420230}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{FD0151B4-7153-49A8-9D90-62A252420230}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{FD0151B4-7153-49A8-9D90-62A252420230}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{FD0151B4-7153-49A8-9D90-62A252420230}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
|
{FD0151B4-7153-49A8-9D90-62A252420230}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
|
{FD0151B4-7153-49A8-9D90-62A252420230}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{FD0151B4-7153-49A8-9D90-62A252420230}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
@ -128,5 +156,7 @@ Global
|
||||||
{09C2933C-23AC-41B7-994D-E8A5184A629C} = {95359B4B-4C85-4B44-A75B-0621905C4CF6}
|
{09C2933C-23AC-41B7-994D-E8A5184A629C} = {95359B4B-4C85-4B44-A75B-0621905C4CF6}
|
||||||
{ED253B01-24F1-43D1-AA0B-079391E105A9} = {0E966C37-7334-4D96-AAF6-9F49FBD166E3}
|
{ED253B01-24F1-43D1-AA0B-079391E105A9} = {0E966C37-7334-4D96-AAF6-9F49FBD166E3}
|
||||||
{741B0B05-CE96-473B-B962-6B0A347DF79A} = {95359B4B-4C85-4B44-A75B-0621905C4CF6}
|
{741B0B05-CE96-473B-B962-6B0A347DF79A} = {95359B4B-4C85-4B44-A75B-0621905C4CF6}
|
||||||
|
{579C3FD2-DFFA-4B64-BFC3-130C11F3568F} = {0E966C37-7334-4D96-AAF6-9F49FBD166E3}
|
||||||
|
{FD0151B4-7153-49A8-9D90-62A252420230} = {95359B4B-4C85-4B44-A75B-0621905C4CF6}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Threading;
|
||||||
using Microsoft.AspNet.Builder;
|
using Microsoft.AspNet.Builder;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
|
|
@ -15,7 +17,7 @@ namespace RoutingSample.Web
|
||||||
services.AddRouting();
|
services.AddRouting();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Configure(IApplicationBuilder builder)
|
public void Configure(IApplicationBuilder app)
|
||||||
{
|
{
|
||||||
var endpoint1 = new RouteHandler((c) =>
|
var endpoint1 = new RouteHandler((c) =>
|
||||||
{
|
{
|
||||||
|
|
@ -24,12 +26,30 @@ namespace RoutingSample.Web
|
||||||
|
|
||||||
var endpoint2 = new RouteHandler((c) => c.Response.WriteAsync("Hello, World!"));
|
var endpoint2 = new RouteHandler((c) => c.Response.WriteAsync("Hello, World!"));
|
||||||
|
|
||||||
var routeBuilder = new RouteBuilder()
|
var routeBuilder = new RouteBuilder(app)
|
||||||
{
|
{
|
||||||
DefaultHandler = endpoint1,
|
DefaultHandler = endpoint1,
|
||||||
ServiceProvider = builder.ApplicationServices,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
routeBuilder.MapRoute("api/status/{item}", c => c.Response.WriteAsync($"{c.GetRouteValue("item")} is just fine."));
|
||||||
|
routeBuilder.MapRoute("localized/{lang=en-US}", b =>
|
||||||
|
{
|
||||||
|
b.Use(next => async (c) =>
|
||||||
|
{
|
||||||
|
var culture = new CultureInfo((string)c.GetRouteValue("lang"));
|
||||||
|
#if DNX451
|
||||||
|
Thread.CurrentThread.CurrentCulture = culture;
|
||||||
|
Thread.CurrentThread.CurrentUICulture = culture;
|
||||||
|
#else
|
||||||
|
CultureInfo.CurrentCulture = culture;
|
||||||
|
CultureInfo.CurrentUICulture = culture;
|
||||||
|
#endif
|
||||||
|
await next(c);
|
||||||
|
});
|
||||||
|
|
||||||
|
b.Run(c => c.Response.WriteAsync($"What would you do with {1000000m:C}?"));
|
||||||
|
});
|
||||||
|
|
||||||
routeBuilder.AddPrefixRoute("api/store", endpoint1);
|
routeBuilder.AddPrefixRoute("api/store", endpoint1);
|
||||||
routeBuilder.AddPrefixRoute("hello/world", endpoint2);
|
routeBuilder.AddPrefixRoute("hello/world", endpoint2);
|
||||||
|
|
||||||
|
|
@ -38,7 +58,7 @@ namespace RoutingSample.Web
|
||||||
|
|
||||||
routeBuilder.AddPrefixRoute("", endpoint2);
|
routeBuilder.AddPrefixRoute("", endpoint2);
|
||||||
|
|
||||||
builder.UseRouter(routeBuilder.Build());
|
app.UseRouter(routeBuilder.Build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,16 +1,15 @@
|
||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.AspNet.Server.Kestrel": "1.0.0-*",
|
"Microsoft.AspNet.Server.Kestrel": "1.0.0-*",
|
||||||
"Microsoft.AspNet.Server.WebListener": "1.0.0-*",
|
"Microsoft.AspNet.Server.WebListener": "1.0.0-*",
|
||||||
"Microsoft.AspNet.Routing": "1.0.0-*"
|
"Microsoft.AspNet.Routing.Extensions": "1.0.0-*"
|
||||||
},
|
},
|
||||||
"commands": {
|
"commands": {
|
||||||
"web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:5001",
|
"web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:5001",
|
||||||
"kestrel": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel --server.urls http://localhost:5000"
|
"kestrel": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel --server.urls http://localhost:5000"
|
||||||
},
|
},
|
||||||
"frameworks": {
|
"frameworks": {
|
||||||
"dnx451": { },
|
"dnx451": { },
|
||||||
"dnxcore50": { }
|
"dnxcore50": { }
|
||||||
},
|
}
|
||||||
"webroot": "wwwroot"
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
RoutingSample.Web
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>579c3fd2-dffa-4b64-bfc3-130c11f3568f</ProjectGuid>
|
||||||
|
<RootNamespace>Microsoft.AspNet.Routing.Extensions</RootNamespace>
|
||||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Resources;
|
||||||
|
|
||||||
|
[assembly: AssemblyMetadata("Serviceable", "True")]
|
||||||
|
[assembly: NeutralResourcesLanguage("en-us")]
|
||||||
|
|
@ -0,0 +1,207 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Microsoft.AspNet.Http;
|
||||||
|
using Microsoft.AspNet.Routing;
|
||||||
|
using Microsoft.AspNet.Routing.Constraints;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Builder
|
||||||
|
{
|
||||||
|
public static class RequestDelegateRouteBuilderExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a route to the <see cref="IRouteBuilder"/> for the given <paramref name="template"/>, and
|
||||||
|
/// <paramref name="handler"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">The <see cref="IRouteBuilder"/>.</param>
|
||||||
|
/// <param name="template">The route template.</param>
|
||||||
|
/// <param name="handler">The <see cref="RequestDelegate"/> route handler.</param>
|
||||||
|
/// <returns>A reference to the <paramref name="builder"/> after this operation has completed.</returns>
|
||||||
|
public static IRouteBuilder MapRoute(this IRouteBuilder builder, string template, RequestDelegate handler)
|
||||||
|
{
|
||||||
|
var route = new Route(
|
||||||
|
new RouteHandler(handler),
|
||||||
|
template,
|
||||||
|
defaults: null,
|
||||||
|
constraints: null,
|
||||||
|
dataTokens: null,
|
||||||
|
inlineConstraintResolver: GetConstraintResolver(builder));
|
||||||
|
|
||||||
|
builder.Routes.Add(route);
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a route to the <see cref="IRouteBuilder"/> for the given <paramref name="template"/>, and
|
||||||
|
/// <paramref name="action"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">The <see cref="IRouteBuilder"/>.</param>
|
||||||
|
/// <param name="action">The action to apply to the <see cref="IApplicationBuilder"/>.</param>
|
||||||
|
/// <param name="handler">The <see cref="RequestDelegate"/> route handler.</param>
|
||||||
|
/// <returns>A reference to the <paramref name="builder"/> after this operation has completed.</returns>
|
||||||
|
public static IRouteBuilder MapRoute(this IRouteBuilder builder, string template, Action<IApplicationBuilder> action)
|
||||||
|
{
|
||||||
|
var nested = builder.ApplicationBuilder.New();
|
||||||
|
action(nested);
|
||||||
|
return builder.MapRoute(template, nested.Build());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a route to the <see cref="IRouteBuilder"/> that only matches HTTP DELETE requests for the given
|
||||||
|
/// <paramref name="template"/>, and <paramref name="handler"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">The <see cref="IRouteBuilder"/>.</param>
|
||||||
|
/// <param name="template">The route template.</param>
|
||||||
|
/// <param name="handler">The <see cref="RequestDelegate"/> route handler.</param>
|
||||||
|
/// <returns>A reference to the <paramref name="builder"/> after this operation has completed.</returns>
|
||||||
|
public static IRouteBuilder MapDelete(this IRouteBuilder builder, string template, RequestDelegate handler)
|
||||||
|
{
|
||||||
|
return builder.MapVerb("DELETE", template, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a route to the <see cref="IRouteBuilder"/> that only matches HTTP DELETE requests for the given
|
||||||
|
/// <paramref name="template"/>, and <paramref name="action"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">The <see cref="IRouteBuilder"/>.</param>
|
||||||
|
/// <param name="template">The route template.</param>
|
||||||
|
/// <param name="action">The action to apply to the <see cref="IApplicationBuilder"/>.</param>
|
||||||
|
/// <returns>A reference to the <paramref name="builder"/> after this operation has completed.</returns>
|
||||||
|
public static IRouteBuilder MapDelete(this IRouteBuilder builder, string template, Action<IApplicationBuilder> action)
|
||||||
|
{
|
||||||
|
return builder.MapVerb("DELETE", template, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a route to the <see cref="IRouteBuilder"/> that only matches HTTP DELETE requests for the given
|
||||||
|
/// <paramref name="template"/>, and <paramref name="handler"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">The <see cref="IRouteBuilder"/>.</param>
|
||||||
|
/// <param name="template">The route template.</param>
|
||||||
|
/// <param name="handler">The <see cref="RequestDelegate"/> route handler.</param>
|
||||||
|
/// <returns>A reference to the <paramref name="builder"/> after this operation has completed.</returns>
|
||||||
|
public static IRouteBuilder MapGet(this IRouteBuilder builder, string template, RequestDelegate handler)
|
||||||
|
{
|
||||||
|
return builder.MapVerb("GET", template, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a route to the <see cref="IRouteBuilder"/> that only matches HTTP DELETE requests for the given
|
||||||
|
/// <paramref name="template"/>, and <paramref name="action"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">The <see cref="IRouteBuilder"/>.</param>
|
||||||
|
/// <param name="template">The route template.</param>
|
||||||
|
/// <param name="action">The action to apply to the <see cref="IApplicationBuilder"/>.</param>
|
||||||
|
/// <returns>A reference to the <paramref name="builder"/> after this operation has completed.</returns>
|
||||||
|
public static IRouteBuilder MapGet(this IRouteBuilder builder, string template, Action<IApplicationBuilder> action)
|
||||||
|
{
|
||||||
|
return builder.MapVerb("GET", template, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a route to the <see cref="IRouteBuilder"/> that only matches HTTP DELETE requests for the given
|
||||||
|
/// <paramref name="template"/>, and <paramref name="handler"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">The <see cref="IRouteBuilder"/>.</param>
|
||||||
|
/// <param name="template">The route template.</param>
|
||||||
|
/// <param name="handler">The <see cref="RequestDelegate"/> route handler.</param>
|
||||||
|
/// <returns>A reference to the <paramref name="builder"/> after this operation has completed.</returns>
|
||||||
|
public static IRouteBuilder MapPost(this IRouteBuilder builder, string template, RequestDelegate handler)
|
||||||
|
{
|
||||||
|
return builder.MapVerb("POST", template, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a route to the <see cref="IRouteBuilder"/> that only matches HTTP DELETE requests for the given
|
||||||
|
/// <paramref name="template"/>, and <paramref name="action"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">The <see cref="IRouteBuilder"/>.</param>
|
||||||
|
/// <param name="template">The route template.</param>
|
||||||
|
/// <param name="action">The action to apply to the <see cref="IApplicationBuilder"/>.</param>
|
||||||
|
/// <returns>A reference to the <paramref name="builder"/> after this operation has completed.</returns>
|
||||||
|
public static IRouteBuilder MapPost(this IRouteBuilder builder, string template, Action<IApplicationBuilder> action)
|
||||||
|
{
|
||||||
|
return builder.MapVerb("POST", template, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a route to the <see cref="IRouteBuilder"/> that only matches HTTP DELETE requests for the given
|
||||||
|
/// <paramref name="template"/>, and <paramref name="handler"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">The <see cref="IRouteBuilder"/>.</param>
|
||||||
|
/// <param name="template">The route template.</param>
|
||||||
|
/// <param name="handler">The <see cref="RequestDelegate"/> route handler.</param>
|
||||||
|
/// <returns>A reference to the <paramref name="builder"/> after this operation has completed.</returns>
|
||||||
|
public static IRouteBuilder MapPut(this IRouteBuilder builder, string template, RequestDelegate handler)
|
||||||
|
{
|
||||||
|
return builder.MapVerb("PUT", template, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a route to the <see cref="IRouteBuilder"/> that only matches HTTP DELETE requests for the given
|
||||||
|
/// <paramref name="template"/>, and <paramref name="action"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">The <see cref="IRouteBuilder"/>.</param>
|
||||||
|
/// <param name="template">The route template.</param>
|
||||||
|
/// <param name="action">The action to apply to the <see cref="IApplicationBuilder"/>.</param>
|
||||||
|
/// <returns>A reference to the <paramref name="builder"/> after this operation has completed.</returns>
|
||||||
|
public static IRouteBuilder MapPut(this IRouteBuilder builder, string template, Action<IApplicationBuilder> action)
|
||||||
|
{
|
||||||
|
return builder.MapVerb("PUT", template, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a route to the <see cref="IRouteBuilder"/> that only matches HTTP requests for the given
|
||||||
|
/// <paramref name="verb"/>, <paramref name="template"/>, and <paramref name="handler"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">The <see cref="IRouteBuilder"/>.</param>
|
||||||
|
/// <param name="verb">The HTTP verb allowed by the route.</param>
|
||||||
|
/// <param name="template">The route template.</param>
|
||||||
|
/// <param name="handler">The <see cref="RequestDelegate"/> route handler.</param>
|
||||||
|
/// <returns>A reference to the <paramref name="builder"/> after this operation has completed.</returns>
|
||||||
|
public static IRouteBuilder MapVerb(
|
||||||
|
this IRouteBuilder builder,
|
||||||
|
string verb,
|
||||||
|
string template,
|
||||||
|
RequestDelegate handler)
|
||||||
|
{
|
||||||
|
var route = new Route(
|
||||||
|
new RouteHandler(handler),
|
||||||
|
template,
|
||||||
|
defaults: null,
|
||||||
|
constraints: new RouteValueDictionary(new { httpMethod = new HttpMethodRouteConstraint(verb) }),
|
||||||
|
dataTokens: null,
|
||||||
|
inlineConstraintResolver: GetConstraintResolver(builder));
|
||||||
|
|
||||||
|
builder.Routes.Add(route);
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a route to the <see cref="IRouteBuilder"/> that only matches HTTP requests for the given
|
||||||
|
/// <paramref name="verb"/>, <paramref name="template"/>, and <paramref name="action"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">The <see cref="IRouteBuilder"/>.</param>
|
||||||
|
/// <param name="verb">The HTTP verb allowed by the route.</param>
|
||||||
|
/// <param name="template">The route template.</param>
|
||||||
|
/// <param name="action">The action to apply to the <see cref="IApplicationBuilder"/>.</param>
|
||||||
|
/// <returns>A reference to the <paramref name="builder"/> after this operation has completed.</returns>
|
||||||
|
public static IRouteBuilder MapVerb(
|
||||||
|
this IRouteBuilder builder,
|
||||||
|
string verb,
|
||||||
|
string template,
|
||||||
|
Action<IApplicationBuilder> action)
|
||||||
|
{
|
||||||
|
var nested = builder.ApplicationBuilder.New();
|
||||||
|
action(nested);
|
||||||
|
return builder.MapVerb(verb, template, nested.Build());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IInlineConstraintResolver GetConstraintResolver(IRouteBuilder builder)
|
||||||
|
{
|
||||||
|
return builder.ServiceProvider.GetRequiredService<IInlineConstraintResolver>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"description": "ASP.NET 5 extension methods for routing requests to application logic and for generating links.",
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git://github.com/aspnet/routing"
|
||||||
|
},
|
||||||
|
"compilationOptions": {
|
||||||
|
"warningsAsErrors": true,
|
||||||
|
"keyFile": "../../tools/Key.snk"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.AspNet.Routing": "1.0.0-*"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net451": { },
|
||||||
|
"dotnet5.4": { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,14 +11,14 @@ namespace Microsoft.AspNet.Routing.Constraints
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constrains the HTTP method of request or a route.
|
/// Constrains the HTTP method of request or a route.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class HttpRouteMethodConstraint : IRouteConstraint
|
public class HttpMethodRouteConstraint : IRouteConstraint
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new <see cref="HttpRouteMethodConstraint"/> that accepts the HTTP methods specified
|
/// Creates a new <see cref="HttpMethodRouteConstraint"/> that accepts the HTTP methods specified
|
||||||
/// by <paramref name="allowedMethods"/>.
|
/// by <paramref name="allowedMethods"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="allowedMethods">The allowed HTTP methods.</param>
|
/// <param name="allowedMethods">The allowed HTTP methods.</param>
|
||||||
public HttpRouteMethodConstraint(params string[] allowedMethods)
|
public HttpMethodRouteConstraint(params string[] allowedMethods)
|
||||||
{
|
{
|
||||||
if (allowedMethods == null)
|
if (allowedMethods == null)
|
||||||
{
|
{
|
||||||
|
|
@ -69,8 +69,8 @@ namespace Microsoft.AspNet.Routing.Constraints
|
||||||
case RouteDirection.UrlGeneration:
|
case RouteDirection.UrlGeneration:
|
||||||
// We need to see if the user specified the HTTP method explicitly. Consider these two routes:
|
// We need to see if the user specified the HTTP method explicitly. Consider these two routes:
|
||||||
//
|
//
|
||||||
// a) Route: template = "/{foo}", Constraints = { httpMethod = new HttpRouteMethodConstraint("GET") }
|
// a) Route: template = "/{foo}", Constraints = { httpMethod = new HttpMethodRouteConstraint("GET") }
|
||||||
// b) Route: template = "/{foo}", Constraints = { httpMethod = new HttpRouteMethodConstraint("POST") }
|
// b) Route: template = "/{foo}", Constraints = { httpMethod = new HttpMethodRouteConstraint("POST") }
|
||||||
//
|
//
|
||||||
// A user might know ahead of time that a URI he/she is generating might be used with a particular HTTP
|
// A user might know ahead of time that a URI he/she is generating might be used with a particular HTTP
|
||||||
// method. If a URI will be used for an HTTP POST but we match on (a) while generating the URI, then
|
// method. If a URI will be used for an HTTP POST but we match on (a) while generating the URI, then
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.AspNet.Builder;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Routing
|
namespace Microsoft.AspNet.Routing
|
||||||
{
|
{
|
||||||
|
|
@ -12,6 +13,11 @@ namespace Microsoft.AspNet.Routing
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IRouteBuilder
|
public interface IRouteBuilder
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the <see cref="IApplicationBuilder"/>.
|
||||||
|
/// </summary>
|
||||||
|
IApplicationBuilder ApplicationBuilder { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the default <see cref="IRouter"/> that is used as a handler if an <see cref="IRouter"/>
|
/// Gets or sets the default <see cref="IRouter"/> that is used as a handler if an <see cref="IRouter"/>
|
||||||
/// is added to the list of routes but does not specify its own.
|
/// is added to the list of routes but does not specify its own.
|
||||||
|
|
|
||||||
|
|
@ -2,9 +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.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
using Microsoft.AspNet.Routing.Template;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Builder
|
namespace Microsoft.AspNet.Builder
|
||||||
|
|
@ -12,7 +10,7 @@ namespace Microsoft.AspNet.Builder
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides extension methods for <see cref="IRouteBuilder"/> to add routes.
|
/// Provides extension methods for <see cref="IRouteBuilder"/> to add routes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class RouteBuilderExtensions
|
public static class MapRouteRouteBuilderExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a route to the <see cref="IRouteBuilder"/> with the specified name and template.
|
/// Adds a route to the <see cref="IRouteBuilder"/> with the specified name and template.
|
||||||
|
|
@ -3,19 +3,35 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.AspNet.Builder;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Routing
|
namespace Microsoft.AspNet.Routing
|
||||||
{
|
{
|
||||||
public class RouteBuilder : IRouteBuilder
|
public class RouteBuilder : IRouteBuilder
|
||||||
{
|
{
|
||||||
public RouteBuilder()
|
public RouteBuilder(IApplicationBuilder applicationBuilder)
|
||||||
|
: this(applicationBuilder, defaultHandler: null)
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public RouteBuilder(IApplicationBuilder applicationBuilder, IRouter defaultHandler)
|
||||||
|
{
|
||||||
|
if (applicationBuilder == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(applicationBuilder));
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplicationBuilder = applicationBuilder;
|
||||||
|
ServiceProvider = applicationBuilder.ApplicationServices;
|
||||||
|
|
||||||
Routes = new List<IRouter>();
|
Routes = new List<IRouter>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IApplicationBuilder ApplicationBuilder { get; }
|
||||||
|
|
||||||
public IRouter DefaultHandler { get; set; }
|
public IRouter DefaultHandler { get; set; }
|
||||||
|
|
||||||
public IServiceProvider ServiceProvider { get; set; }
|
public IServiceProvider ServiceProvider { get; }
|
||||||
|
|
||||||
public IList<IRouter> Routes { get; }
|
public IList<IRouter> Routes { get; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>fd0151b4-7153-49a8-9d90-62a252420230</ProjectGuid>
|
||||||
|
<RootNamespace>Microsoft.AspNet.Routing.Extensions.Tests</RootNamespace>
|
||||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,157 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Http;
|
||||||
|
using Microsoft.AspNet.Http.Internal;
|
||||||
|
using Microsoft.AspNet.Routing;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Moq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Builder
|
||||||
|
{
|
||||||
|
// These are really more like integration tests. They verify that these extensions
|
||||||
|
// add routes that behave as advertised.
|
||||||
|
public class RequestDelegateRouteBuilderExtensionsTest
|
||||||
|
{
|
||||||
|
private static readonly RequestDelegate NullHandler = (c) => Task.FromResult(0);
|
||||||
|
|
||||||
|
public static TheoryData<Action<IRouteBuilder>, Action<HttpContext>> MatchingActions
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new TheoryData<Action<IRouteBuilder>, Action<HttpContext>>()
|
||||||
|
{
|
||||||
|
{ b => { b.MapRoute("api/{id}", NullHandler); }, null },
|
||||||
|
{ b => { b.MapRoute("api/{id}", app => { }); }, null },
|
||||||
|
|
||||||
|
{ b => { b.MapDelete("api/{id}", NullHandler); }, c => { c.Request.Method = "DELETE"; } },
|
||||||
|
{ b => { b.MapDelete("api/{id}", app => { }); }, c => { c.Request.Method = "DELETE"; } },
|
||||||
|
{ b => { b.MapGet("api/{id}", NullHandler); }, c => { c.Request.Method = "GET"; } },
|
||||||
|
{ b => { b.MapGet("api/{id}", app => { }); }, c => { c.Request.Method = "GET"; } },
|
||||||
|
{ b => { b.MapPost("api/{id}", NullHandler); }, c => { c.Request.Method = "POST"; } },
|
||||||
|
{ b => { b.MapPost("api/{id}", app => { }); }, c => { c.Request.Method = "POST"; } },
|
||||||
|
{ b => { b.MapPut("api/{id}", NullHandler); }, c => { c.Request.Method = "PUT"; } },
|
||||||
|
{ b => { b.MapPut("api/{id}", app => { }); }, c => { c.Request.Method = "PUT"; } },
|
||||||
|
|
||||||
|
{ b => { b.MapVerb("PUT", "api/{id}", NullHandler); }, c => { c.Request.Method = "PUT"; } },
|
||||||
|
{ b => { b.MapVerb("PUT", "api/{id}", app => { }); }, c => { c.Request.Method = "PUT"; } },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(MatchingActions))]
|
||||||
|
public async Task Map_MatchesRequest(
|
||||||
|
Action<IRouteBuilder> routeSetup,
|
||||||
|
Action<HttpContext> requestSetup)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var services = CreateServices();
|
||||||
|
|
||||||
|
var context = CreateRouteContext(services);
|
||||||
|
context.HttpContext.Request.Path = new PathString("/api/5");
|
||||||
|
requestSetup?.Invoke(context.HttpContext);
|
||||||
|
|
||||||
|
var builder = CreateRouteBuilder(services);
|
||||||
|
routeSetup(builder);
|
||||||
|
var route = builder.Build();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await route.RouteAsync(context);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Same(NullHandler, context.Handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TheoryData<Action<IRouteBuilder>, Action<HttpContext>> NonmatchingActions
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new TheoryData<Action<IRouteBuilder>, Action<HttpContext>>()
|
||||||
|
{
|
||||||
|
{ b => { b.MapRoute("api/{id}/extra", NullHandler); }, null },
|
||||||
|
{ b => { b.MapRoute("api/{id}/extra", app => { }); }, null },
|
||||||
|
|
||||||
|
{ b => { b.MapDelete("api/{id}", NullHandler); }, c => { c.Request.Method = "GET"; } },
|
||||||
|
{ b => { b.MapDelete("api/{id}", app => { }); }, c => { c.Request.Method = "PUT"; } },
|
||||||
|
{ b => { b.MapDelete("api/{id}/extra", NullHandler); }, c => { c.Request.Method = "DELETE"; } },
|
||||||
|
{ b => { b.MapDelete("api/{id}/extra", app => { }); }, c => { c.Request.Method = "DELETE"; } },
|
||||||
|
{ b => { b.MapGet("api/{id}", NullHandler); }, c => { c.Request.Method = "PUT"; } },
|
||||||
|
{ b => { b.MapGet("api/{id}", app => { }); }, c => { c.Request.Method = "POST"; } },
|
||||||
|
{ b => { b.MapGet("api/{id}/extra", NullHandler); }, c => { c.Request.Method = "GET"; } },
|
||||||
|
{ b => { b.MapGet("api/{id}/extra", app => { }); }, c => { c.Request.Method = "GET"; } },
|
||||||
|
{ b => { b.MapPost("api/{id}", NullHandler); }, c => { c.Request.Method = "MEH"; } },
|
||||||
|
{ b => { b.MapPost("api/{id}", app => { }); }, c => { c.Request.Method = "DELETE"; } },
|
||||||
|
{ b => { b.MapPost("api/{id}/extra", NullHandler); }, c => { c.Request.Method = "POST"; } },
|
||||||
|
{ b => { b.MapPost("api/{id}/extra", app => { }); }, c => { c.Request.Method = "POST"; } },
|
||||||
|
{ b => { b.MapPut("api/{id}", NullHandler); }, c => { c.Request.Method = "BLEH"; } },
|
||||||
|
{ b => { b.MapPut("api/{id}", app => { }); }, c => { c.Request.Method = "HEAD"; } },
|
||||||
|
{ b => { b.MapPut("api/{id}/extra", NullHandler); }, c => { c.Request.Method = "PUT"; } },
|
||||||
|
{ b => { b.MapPut("api/{id}/extra", app => { }); }, c => { c.Request.Method = "PUT"; } },
|
||||||
|
|
||||||
|
{ b => { b.MapVerb("PUT", "api/{id}", NullHandler); }, c => { c.Request.Method = "POST"; } },
|
||||||
|
{ b => { b.MapVerb("PUT", "api/{id}", app => { }); }, c => { c.Request.Method = "HEAD"; } },
|
||||||
|
{ b => { b.MapVerb("PUT", "api/{id}/extra", NullHandler); }, c => { c.Request.Method = "PUT"; } },
|
||||||
|
{ b => { b.MapVerb("PUT", "api/{id}/extra", app => { }); }, c => { c.Request.Method = "PUT"; } },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(NonmatchingActions))]
|
||||||
|
public async Task Map_DoesNotMatchRequest(
|
||||||
|
Action<IRouteBuilder> routeSetup,
|
||||||
|
Action<HttpContext> requestSetup)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var services = CreateServices();
|
||||||
|
|
||||||
|
var context = CreateRouteContext(services);
|
||||||
|
context.HttpContext.Request.Path = new PathString("/api/5");
|
||||||
|
requestSetup?.Invoke(context.HttpContext);
|
||||||
|
|
||||||
|
var builder = CreateRouteBuilder(services);
|
||||||
|
routeSetup(builder);
|
||||||
|
var route = builder.Build();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await route.RouteAsync(context);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Null(context.Handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IServiceProvider CreateServices()
|
||||||
|
{
|
||||||
|
var services = new ServiceCollection();
|
||||||
|
services.AddRouting();
|
||||||
|
services.AddLogging();
|
||||||
|
return services.BuildServiceProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RouteContext CreateRouteContext(IServiceProvider services)
|
||||||
|
{
|
||||||
|
var httpContext = new DefaultHttpContext();
|
||||||
|
httpContext.RequestServices = services;
|
||||||
|
return new RouteContext(httpContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IRouteBuilder CreateRouteBuilder(IServiceProvider services)
|
||||||
|
{
|
||||||
|
var applicationBuilder = new Mock<IApplicationBuilder>();
|
||||||
|
applicationBuilder.SetupAllProperties();
|
||||||
|
|
||||||
|
applicationBuilder
|
||||||
|
.Setup(b => b.New().Build())
|
||||||
|
.Returns(NullHandler);
|
||||||
|
|
||||||
|
applicationBuilder.Object.ApplicationServices = services;
|
||||||
|
|
||||||
|
var routeBuilder = new RouteBuilder(applicationBuilder.Object);
|
||||||
|
return routeBuilder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"compilationOptions": {
|
||||||
|
"warningsAsErrors": true
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.AspNet.Http": "1.0.0-*",
|
||||||
|
"Microsoft.AspNet.Routing.Extensions": "1.0.0-*",
|
||||||
|
"Microsoft.AspNet.Testing": "1.0.0-*",
|
||||||
|
"Microsoft.Extensions.DependencyInjection": "1.0.0-*",
|
||||||
|
"Microsoft.Extensions.Logging.Testing": "1.0.0-*",
|
||||||
|
"xunit.runner.aspnet": "2.0.0-aspnet-*"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"dnxcore50": {
|
||||||
|
"dependencies": {
|
||||||
|
"moq.netcore": "4.4.0-beta8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dnx451": {
|
||||||
|
"dependencies": {
|
||||||
|
"Moq": "4.2.1312.1622"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"commands": {
|
||||||
|
"test": "xunit.runner.aspnet"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,7 +15,7 @@ namespace Microsoft.AspNet.Routing.Constraints
|
||||||
public void HttpMethodRouteConstraint_IncomingRequest_AcceptsAllowedMethods(string httpMethod)
|
public void HttpMethodRouteConstraint_IncomingRequest_AcceptsAllowedMethods(string httpMethod)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var constraint = new HttpRouteMethodConstraint("GET", "post");
|
var constraint = new HttpMethodRouteConstraint("GET", "post");
|
||||||
|
|
||||||
var httpContext = new DefaultHttpContext();
|
var httpContext = new DefaultHttpContext();
|
||||||
httpContext.Request.Method = httpMethod;
|
httpContext.Request.Method = httpMethod;
|
||||||
|
|
@ -36,7 +36,7 @@ namespace Microsoft.AspNet.Routing.Constraints
|
||||||
public void HttpMethodRouteConstraint_IncomingRequest_RejectsOtherMethods(string httpMethod)
|
public void HttpMethodRouteConstraint_IncomingRequest_RejectsOtherMethods(string httpMethod)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var constraint = new HttpRouteMethodConstraint("GET", "post");
|
var constraint = new HttpMethodRouteConstraint("GET", "post");
|
||||||
|
|
||||||
var httpContext = new DefaultHttpContext();
|
var httpContext = new DefaultHttpContext();
|
||||||
httpContext.Request.Method = httpMethod;
|
httpContext.Request.Method = httpMethod;
|
||||||
|
|
@ -57,7 +57,7 @@ namespace Microsoft.AspNet.Routing.Constraints
|
||||||
public void HttpMethodRouteConstraint_UrlGeneration_AcceptsAllowedMethods(string httpMethod)
|
public void HttpMethodRouteConstraint_UrlGeneration_AcceptsAllowedMethods(string httpMethod)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var constraint = new HttpRouteMethodConstraint("GET", "post");
|
var constraint = new HttpMethodRouteConstraint("GET", "post");
|
||||||
|
|
||||||
var httpContext = new DefaultHttpContext();
|
var httpContext = new DefaultHttpContext();
|
||||||
var route = Mock.Of<IRouter>();
|
var route = Mock.Of<IRouter>();
|
||||||
|
|
@ -77,7 +77,7 @@ namespace Microsoft.AspNet.Routing.Constraints
|
||||||
public void HttpMethodRouteConstraint_UrlGeneration_RejectsOtherMethods(string httpMethod)
|
public void HttpMethodRouteConstraint_UrlGeneration_RejectsOtherMethods(string httpMethod)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var constraint = new HttpRouteMethodConstraint("GET", "post");
|
var constraint = new HttpMethodRouteConstraint("GET", "post");
|
||||||
|
|
||||||
var httpContext = new DefaultHttpContext();
|
var httpContext = new DefaultHttpContext();
|
||||||
var route = Mock.Of<IRouter>();
|
var route = Mock.Of<IRouter>();
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,9 @@ using Microsoft.AspNet.Builder;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Routing.Constraints;
|
using Microsoft.AspNet.Routing.Constraints;
|
||||||
using Microsoft.AspNet.Testing;
|
using Microsoft.AspNet.Testing;
|
||||||
using Microsoft.Extensions.Logging.Testing;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Logging.Testing;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -1490,15 +1491,14 @@ namespace Microsoft.AspNet.Routing
|
||||||
|
|
||||||
private static IRouteBuilder CreateRouteBuilder()
|
private static IRouteBuilder CreateRouteBuilder()
|
||||||
{
|
{
|
||||||
var routeBuilder = new RouteBuilder();
|
var services = new ServiceCollection();
|
||||||
|
services.AddSingleton<IInlineConstraintResolver>(_inlineConstraintResolver);
|
||||||
|
|
||||||
|
var applicationBuilder = Mock.Of<IApplicationBuilder>();
|
||||||
|
applicationBuilder.ApplicationServices = services.BuildServiceProvider();
|
||||||
|
|
||||||
|
var routeBuilder = new RouteBuilder(applicationBuilder);
|
||||||
routeBuilder.DefaultHandler = new RouteHandler(NullHandler);
|
routeBuilder.DefaultHandler = new RouteHandler(NullHandler);
|
||||||
|
|
||||||
var serviceProviderMock = new Mock<IServiceProvider>();
|
|
||||||
serviceProviderMock.Setup(o => o.GetService(typeof(IInlineConstraintResolver)))
|
|
||||||
.Returns(_inlineConstraintResolver);
|
|
||||||
routeBuilder.ServiceProvider = serviceProviderMock.Object;
|
|
||||||
|
|
||||||
return routeBuilder;
|
return routeBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,26 +96,28 @@ namespace Microsoft.AspNet.Routing.Tests
|
||||||
var routeBuilder = CreateRouteBuilder();
|
var routeBuilder = CreateRouteBuilder();
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
var ex = Assert.Throws<ArgumentException>(
|
var ex = Assert.Throws<ArgumentException>(() =>
|
||||||
() => routeBuilder.MapRoute("mockName",
|
{
|
||||||
"{controller}/{action}/{id:int=12?}",
|
routeBuilder.MapRoute(
|
||||||
defaults: new { id = 13 },
|
"mockName",
|
||||||
constraints: null));
|
"{controller}/{action}/{id:int=12?}",
|
||||||
|
defaults: new { id = 13 },
|
||||||
|
constraints: null);
|
||||||
|
});
|
||||||
|
|
||||||
Assert.Equal(message, ex.Message);
|
Assert.Equal(message, ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IRouteBuilder CreateRouteBuilder()
|
private static IRouteBuilder CreateRouteBuilder()
|
||||||
{
|
{
|
||||||
var routeBuilder = new RouteBuilder();
|
var services = new ServiceCollection();
|
||||||
|
services.AddSingleton<IInlineConstraintResolver>(_inlineConstraintResolver);
|
||||||
|
|
||||||
routeBuilder.DefaultHandler = new Mock<IRouter>().Object;
|
var applicationBuilder = Mock.Of<IApplicationBuilder>();
|
||||||
|
applicationBuilder.ApplicationServices = services.BuildServiceProvider();
|
||||||
var serviceProviderMock = new Mock<IServiceProvider>();
|
|
||||||
serviceProviderMock.Setup(o => o.GetService(typeof(IInlineConstraintResolver)))
|
|
||||||
.Returns(_inlineConstraintResolver);
|
|
||||||
routeBuilder.ServiceProvider = serviceProviderMock.Object;
|
|
||||||
|
|
||||||
|
var routeBuilder = new RouteBuilder(applicationBuilder);
|
||||||
|
routeBuilder.DefaultHandler = Mock.Of<IRouter>();
|
||||||
return routeBuilder;
|
return routeBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue