带有缺省路由的租户区域路由

本文关键字:区域 路由 缺省路由 | 更新日期: 2023-09-27 18:03:20

所以我有一个网站,基本上每个租户有一个"面积"。所以它会显示为www.site.com/它会用一个区域进入到groups页面

事情是,我也有一个默认的路线以外的区域,所以你可以去www.site.com/,这将带你到实际的~/Views/Home/Index页。但是,如果您尝试键入www.site.com/Home/Index或说页面要创建一个新组www.site.com/Group/Create,它认为它需要转到不存在的区域,并给出404资源无法找到。

RouteConfig.cs

中的默认路由
        routes.MapRoute(
            "Default",
            "{controller}/{action}/{id}",
             new { controller = "Home", action = "Index", id = UrlParameter.Optional },
             new[] { "TicketSystem.Controllers" }
        );

这是该区域的路由配置:

        context.MapRoute(
            "Group_default",
            "{group}/{controller}/{action}/{id}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            new[] { "TicketSystem.Areas.Group.Controllers" }); 

所以{group}是你当前访问的任何组,然后它会转到该组的常规控制器/动作。然而,对于默认路由,无论如何它似乎仍然会转到区域路由。

我在想可能会有退路。所以当它试图去那个区域,但它找不到正确的控制器/动作时,它会检查默认路由。如果它仍然找不到任何东西,它将给出404错误,资源无法找到。虽然我不确定如何做到这一点。

因此,使www.site.com/工作,并允许www.site.com/Home/Index工作

带有缺省路由的租户区域路由

问题是,当您尝试访问/Home/Index时,路由引擎不知道"Home",您的意思是控制器名称或组名称!

为了解决这个问题,你可以创建一个自定义路由约束来检查请求url中的group值是否为应用程序中的有效控制器名。如果是,该请求将不会被区域路由注册定义处理。

public class GroupNameConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName,
                       RouteValueDictionary values, RouteDirection routeDirection)
    {
        var asm = Assembly.GetExecutingAssembly();
        //Get all the controller names
        var controllerTypes = (from t in asm.GetExportedTypes()
            where typeof(IController).IsAssignableFrom(t)
            select t.Name.Replace("Controller", ""));
        var groupName = values["group"];
        if (groupName != null)
        {
            if (controllerTypes.Any(x => x.Equals(groupName.ToString(),
                                                       StringComparison.OrdinalIgnoreCase)))
            {
                return false;
            }
        }
        return true;
    }
}

在注册区域路由时注册此约束。

    public override void RegisterArea(AreaRegistrationContext context) 
    {
        context.MapRoute(
            "Group_default",
            "{group}/{controller}/{action}/{id}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            new { anything = new GroupNameConstraint() }

        );
    }

这应该工作,假设你永远不会有一个groupName相同的控制器名称(例如:Home)