简体   繁体   中英

ASP.NET Core routing middleware to place tenant name in url

I am trying to write a webapp that uses tenants and am wondering how I can write a middleware to add the tenant name to the current URL.

This is a sample that I have so far and it doesn't work at all.

This is the route that I declare:

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

This is placed in the Configure section in my 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();
    }
});

If I load up my application and log in, it shows this:

https://localhost:44365/Applications/Applications

instead of

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

I can manually add TenantName and it works but if I move to another page, it loses it again.

EDIT:

I tried creating a custom route builder but it doesn't work if my url is like this

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;
}

I have also placed this before my normal app.UseMvc();

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM