在您的应用程序中如何区分每个网站?如果我们假设每个租户都由唯一的域名或子域名来标识,那么您可以使用一条路由和一些路由来完成路由RouteConstraints
。创建两个约束,一个用于控制器,另一个用于操作。假设您的数据库中有一些表列出了特定租户的可用控制器/操作,则您的约束如下:
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);
}
}
}
然后,在 Global.asax.cs 中定义您的路线,如下所示:
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(),}
);
}
当请求传入时,约束将检查控制器和操作对于域是否有效,以便只有对该租户有效的控制器和操作才会通过 RouteConstraint。