Tenant-specific routes for dynamically loaded modules

南笙酒味 提交于 2019-12-01 14:04:50

How will each website be distinguished in your app? If we assume each tenant will be identified by a unique domain name or subdomain name, then you can accomplish your routing with one route and some RouteConstraints. Create two constraints, one for controllers, the other for actions. Assuming that you will have tables in your database which list the available controllers/actions for a specific tenant, your constraints would be as follows:

using System; 
using System.Web; 
using System.Web.Routing;  

namespace ExampleApp.Extensions 
{ 
    public class IsControllerValidForTenant : IRouteConstraint
    {
        public IsControllerValidForTenant() { }

        private DbEntities _db = new DbEntities();

        public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
        {
            // determine domain
            var domainName = httpContext.Request.Url.DnsSafeHost;
            var siteId = _db.Sites.FirstorDefault(s => s.DomainName == domainName).SiteId;
            // passed constraint if this controller is valid for this tenant
            return (_db.SiteControllers.Where(sc => sc.Controller == values[parameterName].ToString() && sc.SiteId == siteId).Count() > 0);
        }
    }

    public class IsActionValidForTenant : IRouteConstraint
    {
        public IsActionValidForTenant() { }

        private DbEntities _db = new DbEntities();

        public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
        {
            // determine domain
            var domainName = httpContext.Request.Url.DnsSafeHost;
            var siteId = _db.Sites.FirstorDefault(s => s.DomainName == domainName).SiteId;
            // passed constraint if this action is valid for this tenant
            return (_db.SiteActions.Where(sa => sa.Action == values[parameterName].ToString() && sa.SiteId == siteId).Count() > 0);
        }
    }
}

Then, in Global.asax.cs, define your route as follows:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
        new { controller = new IsControllerValidForTenant(), action = new IsActionValidForTenant(),}
    );
}

When a request comes in, the constraints will examine whether the controller and action are valid for the domain, so that only valid controllers and actions for that tenant will pass the RouteConstraints.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!