对于ASP.NET MVC 5中的多租户应用程序,我创建了一个自定义IRouteConstraint来检查基本URL中是否存在子域,如client1.myapplication.com或client2.application.com。
public class TenantRouteConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
string appSetting = ConfigurationManager.AppSettings[AppSettings.IsMultiTenancyEnabled];
bool isMultiTenancyEnabled = false;
bool isParsedCorrectly = bool.TryParse(appSetting, out isMultiTenancyEnabled);
if (isMultiTenancyEnabled)
{
string subdomain = httpContext.GetSubdomain();
if (subdomain != null && !values.ContainsKey("subdomain"))
{
values.Add("subdomain", subdomain);
}
return string.IsNullOrEmpty(subdomain) ? false : true;
}
else
{
return true;
}
}
}
以下是路线配置设置:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreWindowsLoginRoute();
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new string[] { "Dime.Scheduler.WebUI.Controllers" },
constraints: new { TenantAccess = new TenantRouteConstraint() }
);
}
}
路线约束非常有效但我需要更好地理解这个过程。我想知道当下面的方法返回FALSE时会发生什么。最终的结果是HTTP错误403.14 - 禁止页面,但有什么方法可以拦截它来呈现我自己的自定义页面?我通常在全局Asax文件中捕获这些错误,但在这种情况下,它永远不会到达那里。
这是否与没有任何匹配请求的路由有关?如果没有找到匹配项,有没有办法重定向到自定义页面?
答案 0 :(得分:1)
在与路由关联的任何路由约束返回false之后,路由被视为不匹配,并且.NET路由框架将检查集合中注册的下一个路由(匹配是从第一个路由开始的顺序执行的到集合中注册的最后一条路线。)
最终结果是HTTP错误403.14 - 禁止页面,但有什么方法可以拦截它来呈现我自己的自定义页面?
您可以通过继承RouteBase(或继承Route)来更精确地控制路由。有一个很好的基于域的路由here的例子。
这样做的关键是确保实现这两种方法。 GetRouteData
用于分析请求以确定它是否匹配,如果匹配则返回路由值的字典(如果不是,则返回null)。 GetVirtualPath
是获取路由值列表的地方,如果它们匹配,您应该(通常)返回在匹配的GetRouteData
方法中输入的相同URL。只要您在MVC中使用GetVirtualPath
或ActionLink
,就会调用RouteLink
,因此提供实现通常很重要。
您只需在GetRouteData
中返回正确的一组路线值,即可确定路线指向的网页。