首页 > 解决方案 > ASP.NET Core 路由中间件在 url 中放置租户名称

问题描述

我正在尝试编写一个使用租户的 web 应用程序,并且想知道如何编写一个中间件来将租户名称添加到当前 URL。

这是我到目前为止的一个示例,它根本不起作用。

这是我声明的路线:

routes.MapRoute(
  name: "tenants",
  template: "{tenantName}/{area:exists}/{controller=Home}/{action=Index}/{id?}"
);

这放置在我的 Startup.cs 的配置部分中

app.Use(async (context, next) => {
    if (context.User.Identity.IsAuthenticated == true)
    {
        string originalPath = context.Request.Path.Value;
        context.Items["originalPath"] = originalPath;
        var additionalPath = "/TenantName" + originalPath;
        context.Request.Path = additionalPath;
        await next();
    }
});

如果我加载我的应用程序并登录,它会显示:

https://localhost:44365/Applications/Applications

代替

https://localhost:44365/TenantName/Applications/Applications

我可以手动添加 TenantName 并且它可以工作,但是如果我移动到另一个页面,它会再次丢失。

编辑:

我尝试创建一个自定义路由构建器,但如果我的网址是这样的,它就不起作用

https://localhost:44365/TenantName/Applications/Applications/12345

app.UseRouter(routeBuilder => {
    var template = "{tenant}/{area:exists}/{controller=Home}/{action=Index}/{id?}";
    routeBuilder.MapMiddlewareRoute(template, appBuilder => {
        appBuilder.Use(async (context, next) => {
            var routeData = context.GetRouteData();
            context.Request.Path = getNormalizedPath(routeData);
            await next();
        });
        appBuilder.UseMvc(rb => {
            rb.MapRoute(name: "tenantRoute", template: template);
        });
    });
});

private string getNormalizedPath(RouteData routeData)
{
    var tenant = routeData.Values["tenant"];
    var area = routeData.Values["area"];
    var controller = routeData.Values["controller"];
    var action = routeData.Values["action"];

    var url = "/" + tenant + "/" + area + "/" + controller + "/" + action;
    return url;
}

我也把它放在我的普通 app.UseMvc();

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

解决方案


Please try this:

app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{tenantName=test}/{controller}/{action=Index}/{id?}");
    });

After this your your site will open like:

https://localhost:44365/TenantName/Applications/Applications

instead of

https://localhost:44365/Applications/Applications

Update: tenant name by default is test but can be passed from route at any place. There are multiple ways to do that, available on web. A simple example can be like:

[Route("{tenantName = TEST1}/{controller}/{action}/{id?}")]
public IActionResult Index()
{
   return View();
}

Here tenant name is test1, url is like: https://localhost:44365/test1/Applications/Applications


推荐阅读