問題場景
基於 ASP.NET Core 路由模板(route template)從 url 字符串取值,路由模板是 "/{blogApp}/{postType}/{idOrSlug}.html"
,需要取值的博文 url 地址示例 https://www.cnblogs.com/cmt/p/14408628.html
實現代碼
參考 ASP.NET Core 源碼中的測試代碼 RouteTest.cs#L56,通過 Route.RouteAsync()
方法實現了,RouteTest 中好幾處用了 Mock,這里實現時沒有使用 Mock。
實現代碼如下
class Program
{
static async Task Main(string[] args)
{
var requestPath = "/cmt/p/14408628.html";
var routeTemplate = "/{blogApp}/{postType}/{idOrSlug}.html";
var routeHandler = new RouteHandler((context) => null);
IServiceCollection services = new ServiceCollection();
services.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance);
services.AddOptions<RouteOptions>();
var sp = services.BuildServiceProvider();
var routeOptions = sp.GetRequiredService<IOptions<RouteOptions>>();
var inlineConstraintResolver = new DefaultInlineConstraintResolver(routeOptions, sp);
var route = new Route(
routeHandler,
routeTemplate,
defaults: null,
constraints: new RouteValueDictionary(),
dataTokens: null,
inlineConstraintResolver: inlineConstraintResolver);
var httpContext = new DefaultHttpContext();
httpContext.Request.Path = new PathString(requestPath);
httpContext.RequestServices = sp;
var routeContext = new RouteContext(httpContext);
await route.RouteAsync(routeContext);
Console.WriteLine("blogApp: " + routeContext.RouteData.Values["blogApp"]);
Console.WriteLine("postType: " + routeContext.RouteData.Values["postType"]);
Console.WriteLine("idOrSlug: " + routeContext.RouteData.Values["idOrSlug"]);
}
}
輸出結果如下
blogApp: cmt
postType: p
idOrSlug: 14408628