我正在尝试构建一个附加到 MVC 区域的“租户”子域路由。在这种情况下,我有一个名为“租户”的区域,它有两个控制器;公共和管理员。如果匹配,我的自定义路由用于获取子域,然后将它们路由到正确的 Controller-Action-Area。
该项目的基础来自以下 http://www.matrichard.com/post/asp.net-mvc-5-routing-with-subdomain
我遇到的问题出在自定义子域路由中。当我点击Public/Index
Route 时,routeData
返回 null 并且我看到以下错误。虽然如果路线是/admin
它返回正确的routeData
。
“/”应用程序中的服务器错误。
匹配的路由不包含必需的“控制器”路由值。
它似乎也总是使用 RouteDebugger 工具匹配,这是我问题的线索吗?
示例路线:
控制器=公共行动=索引,区域=租户
http://tenant1.mydomain.com:8080/
http://tenant1.mydomain.com:8080/logon
控制器=管理操作=索引,区域=租户
http://tenant1.mydomain.com:8080/admin
http://tenant1.mydomain.com:8080/admin/edit
--
子域路由P.cs
public class SubdomainRouteP : Route
{
public string Domain { get; set; }
public SubdomainRouteP(string domain, string url, RouteValueDictionary defaults): this(domain, url, defaults, new MvcRouteHandler())
{
}
public SubdomainRouteP(string domain, string url, object defaults): this(domain, url, new RouteValueDictionary(defaults), new MvcRouteHandler())
{
}
public SubdomainRouteP(string domain, string url, object defaults, IRouteHandler routeHandler): this(domain, url, new RouteValueDictionary(defaults), routeHandler)
{
}
public SubdomainRouteP(string domain, string url, RouteValueDictionary defaults, IRouteHandler routeHandler): base(url, defaults, routeHandler)
{
this.Domain = domain;
}
public override RouteData GetRouteData(HttpContextBase httpContext)
{
//
// routeData object returns null in some cases
//
var routeData = base.GetRouteData(httpContext);
var subdomain = httpContext.Request.Url.Host.Split('.').First();
string[] blacklist = { "www", "mydomain", "localhost" };
// This will ignore anything that is not a client tenant prefix
if (blacklist.Contains(subdomain))
{
return null; // Continue to the next route
}
// Why is this NULL?
if (routeData == null)
{
routeData = new RouteData(this, new MvcRouteHandler());
}
routeData.DataTokens["Area"] = "Tenant";
routeData.DataTokens["UseNamespaceFallback"] = bool.FalseString;
routeData.Values.Add("subdomain", subdomain);
// IMPORTANT: Always return null if there is no match.
// This tells .NET routing to check the next route that is registered.
return routeData;
}
}
路由配置.cs
routes.Add("Admin_Subdomain", new SubdomainRouteP(
"{client}.mydomain.com", //of course this should represent the real intent…like I said throwaway demo project in local IIS
"admin/{action}/{id}",
new { controller = "Admin", action = "Index", id = UrlParameter.Optional }));
routes.Add("Public_Subdomain", new SubdomainRouteP(
"{client}.mydomain.com", //of course this should represent the real intent…like I said throwaway demo project in local IIS
"{controller}/{action}/{id}",
new { controller = "Public", action = "Index", id = UrlParameter.Optional }));
// This is the MVC default Route
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
下面的 Url 为我提供了来自 RouteDebugger 的以下结果。在测试 1 和 2 中,路由仍然匹配 /admin。
测试 1 失败:http://tenant.mydomain.com/
失败的测试 2:http://tenant.mydomain.com/logon
成功3:http://tenant.mydomain.com/admin
匹配 URL 默认值
真的
admin/{action}/{id}
controller = Admin, action = Index
真的
{controller}/{action}/{id}
controller = Public, action = Index