IApplicationBuilder Map分支在ASP.NET 5中无法正常工作

时间:2015-07-25 17:53:18

标签: c# owin asp.net-core asp.net-core-mvc

我尝试根据请求网址的第一个文件夹段实现多租户。

考虑我的创业公司的以下片段。

foreach (SiteFolder f in allFolders)
{
    PathString path = new PathString("/" + f.FolderName);
    app.Map(path,
    siteApp =>
    {
        //here I'm trying to specify a different auth cookie name for folder sites and some other configuration
        // but problem happens even with no code here at all
        // I also tried adding the folder specific routes here but still 404
    });
}

app.UseMvc(routes =>
{
    List<SiteFolder> allFolders = siteRepo.GetAllSiteFoldersNonAsync();

    foreach (SiteFolder f in allFolders)
    {
        routes.MapRoute(
        name: f.FolderName + "Default",
        template: f.FolderName + "/{controller}/{action}/{id?}",
        defaults: new { controller = "Home", action = "Index" },
        constraints: new { name = new SiteFolderRouteConstraint(f.FolderName) }
    );

    routes.MapRoute(
        name: "default",
        template: "{controller}/{action}/{id?}",
        defaults: new { controller = "Home", action = "Index" });
});

如果我在顶部注释app.Map,那么我的路由按预期工作,否则如果我在与文件夹路由相同的文件夹名称上分支,则文件夹url all会产生IIS 404页面。

我想也许siteApp没有看到添加到应用程序的路由所以我尝试将路由添加到siteApp但它仍然导致404。

类似的方法在MVC 5中对我有用,我觉得框架中存在错误(beta5)或者我错过了关于分支和新框架的一些重要概念。

1 个答案:

答案 0 :(得分:2)

这正是Map在Katana中的工作方式,并且应该在ASP.NET 5中工作。

Map要注意的最重要的事情是当请求路径对应于注册路径时,它总是终止请求。换句话说,当路径与路径参数匹配时,永远不会执行app.Map调用后注册的中间件,这就是您的app.UseMvc中间件永远不会在您的配置中执行的原因。

由于您未在app.Map委托中处理请求,因此会执行默认处理程序并应用404响应。

您应该尝试使用此扩展方法。与app.Map不同,它永远不会停止处理请求,并且基本上实现了我所说的“条件中间件处理”方案:

public static IApplicationBuilder UseWhen(
    [NotNull] this IApplicationBuilder app,
    [NotNull] Func<HttpContext, bool> condition,
    [NotNull] Action<IApplicationBuilder> configuration) {
    var builder = app.New();
    configuration(builder);

    return app.Use(next => {
        builder.Run(next);

        var branch = builder.Build();

        return context => {
            if (condition(context)) {
                return branch(context);
            }

            return next(context);
        };
    });
}

它是专为AspNet.Security.OpenIdConnect.Server样本开发的,但您当然可以在任何地方使用它。

您可以在那里看到它:https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/blob/vNext/samples/Mvc/Mvc.Server/Startup.cs#L46-L80

// Create a new branch where the registered middleware will be executed only for API calls.
app.UseWhen(context => context.Request.Path.StartsWithSegments(new PathString("/api")), branch => {
    branch.UseOAuthBearerAuthentication(options => {
        options.AutomaticAuthentication = true;
        options.Audience = "http://localhost:54540/";
        options.Authority = "http://localhost:54540/";
    });
});