【问题标题】:ASP.NET Core routing middleware to place tenant name in urlASP.NET Core 路由中间件将租户名称放在 url
【发布时间】:2019-11-27 16:14:43
【问题描述】:

我正在尝试编写一个使用租户的 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();

【问题讨论】:

  • 你有没有试过在public async Task InvokeAsync(HttpContext context)里面做这个操作
  • 您好!我不太明白你的意思?我认为我不能在我的配置部分中使用它?
  • 抱歉,这是注册中间件的另一种方式,您将创建一个扩展方法并在您的配置方法IApplicationBuilder UseClientNameMapper(this IApplicationBuilder applicationBuilder) 中调用它。在启动配置方法app.UseClientNameMapper();
  • 感谢您的回复。你有我可以关注的样本吗?我真的不明白你在说什么。

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


【解决方案1】:

请试试这个:

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

在此之后,您的网站将打开如下:

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

而不是

https://localhost:44365/Applications/Applications

更新:租户名称默认为 test,但可以在任何地方从路由传递。有多种方法可以做到这一点,可以在网上找到。一个简单的例子可以是:

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

这里的租户名称是 test1,url 是这样的: https://localhost:44365/test1/Applications/Applications

【讨论】:

  • 您好,感谢您的回答。但是现在测试是静态的。有没有办法通过cookie获取它并在url中替换它?
  • 您可以从 cookie 甚至配置文件中获取并稍后设置
  • 感谢您的更新。现在的问题是我不知道如何实际更改租户名称。我是否在 actionfilter 中执行此操作?
  • 是的,Actionfilter 是一个好地方,您可以创建自定义操作过滤器并将其用于所有视图。否则 Route 本身就是 actionfilter。如果该名称是静态的,您也可以在启动文件中进行硬编码
猜你喜欢
  • 2010-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-10
  • 1970-01-01
  • 2021-05-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多