我尝试根据请求网址的第一个文件夹段实现多租户。
考虑我的创业公司的以下片段。
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)或者我错过了关于分支和新框架的一些重要概念。
答案 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
样本开发的,但您当然可以在任何地方使用它。
// 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/";
});
});