aspnetcore/samples/RoutingSample/Startup.cs

152 lines
5.7 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Routing;
using Microsoft.AspNet.Routing.HttpMethod;
using Microsoft.AspNet.Routing.Lambda;
using Microsoft.AspNet.Routing.Legacy;
using Microsoft.AspNet.Routing.Owin;
using Microsoft.AspNet.Routing.Template;
using Microsoft.AspNet.Routing.Tree;
using Owin;
namespace RoutingSample
{
internal class Startup
{
public void Configuration(IAppBuilder app)
{
// Configuring the router places it in the OWIN pipeline and retuns an IRouteBuilder which is used
// To create routes - all routes are directed to nested pipelines.
var router = app.UseRouter();
// At the simplest level - we can support microframework style routing.
//
// This route matches a prefix of the request path, and a specific HTTP method.
router.Get("1/echo", async (context) =>
{
string url = (string)context["owin.RequestPath"];
await WriteAsync(context, url);
});
// This route takes a lambda, and can apply arbitrary criteria for routing without needing to couple
// to an object model.
router.On(context => ((string)context["owin.RequestPath"]).StartsWith("2"), async (context) =>
{
string url = (string)context["owin.RequestPath"];
await WriteAsync(context, url);
});
// The return value is an IRouteEndpoint - extension method friendly for adding more routes and different
// route types.
//
// All of these routes go to the same delegate.
router.Get("3/Store", async (context) =>
{
string method = (string)context["owin.RequestMethod"];
await WriteAsync(context, method);
})
.Post("3/Store/Checkout")
.On(context => ((string)context["owin.RequestPath"]).StartsWith("3/api"));
// Routing to a middleware using IAppBuilder -- allowing routing to a more complex pipeline.
router.ForApp((builder) => builder.Use(async (context, next) =>
{
await context.Response.WriteAsync("Hello, World!");
}))
.Get("4/Hello")
.Post("4/Hello/World");
// Nested Router
router.ForApp((builder) =>
{
var nested = builder.UseRouter();
nested.Get(async (context) => await WriteAsync(context, "Get"));
nested.Post(async (context) => await WriteAsync(context, "Post"));
})
.Get("5/Store");
// MVC/WebAPI Stuff below - using 'tradition' template routes.
// Routing with parameter capturing - the route data is stored in the owin context
router.ForApp((builder) => builder.Use(async (context, next) =>
{
string controller = (string)context.Environment.GetRouteMatchValues()["controller"];
await context.Response.WriteAsync(controller);
}))
.AddTemplateRoute("6/api/{controller}", new HttpRouteValueDictionary(new { controller = "Home" }));
// Routing with data tokens - these are added to the context when a route matches
// This technique can be used for MVC/Web API to perform action selection as part of routing
router.ForApp((builder) => builder.Use(async (context, next) =>
{
string stringValue = (string)context.Environment["myapp_StringValue"];
await context.Response.WriteAsync(stringValue);
}))
.AddTemplateRoute("7", null, null, data: new HttpRouteValueDictionary(new { myapp_StringValue = "cool" }));
// The route engine can be provided as a parameter to the app builder function so that it can be
// captured and used inside of the application.
//
// It's also provided as part of the owin context on a routed request for apps that would prefer
// a stateless style.
router.ForApp((builder, engine) => builder.Use(async (context, next) =>
{
if (Object.Equals(engine, context.Environment.GetRouteEngine()))
{
await context.Response.WriteAsync(engine.GetType().ToString());
}
else
{
await next();
}
}))
.AddTemplateRoute("8");
// Generating a link by name
router.ForApp((builder, engine) => builder.Use(async (context, next) =>
{
string url = engine.GetUrl("ByName", context.Environment, new HttpRouteValueDictionary(new { })).Url;
await context.Response.WriteAsync(url);
}))
.AddTemplateRoute("ByName", "9/{value1}", new HttpRouteValueDictionary(new { value1 = "Cool" }));
// Tree Routing
var tree = router.AddTreeRoute();
tree.Path("10/api").Parameter("controller").Endpoint(router.ForApp((builder) => builder.Use(async (context, next) =>
{
string url = context.Request.Uri.PathAndQuery;
await context.Response.WriteAsync(url);
})));
tree.Build();
}
private static Task WriteAsync(IDictionary<string, object> context, string value)
{
var response = (Stream)context["owin.ResponseBody"];
var bytes = Encoding.UTF8.GetBytes(value);
return response.WriteAsync(bytes, 0, bytes.Length);
}
}
}