【问题标题】:How can I dynamically add to the ASP.NET MVC RouteTable?如何动态添加到 ASP.NET MVC RouteTable?
【发布时间】:2011-06-18 11:05:03
【问题描述】:

我们的网站上有一个区域,人们可以在这里注册并在我们希望托管在 ~/pageSlug 的网站上获得他们自己的页面。我尝试使用 Global.asax 中的规则来执行此操作,但这破坏了允许 ~/Controller 直接映射到 Index 操作的基本默认路由。我不允许在 userSlug 前面放置任何类型的分隔符,因此 ~/p/pageSlug 在这里并不是一个真正的选择。

在将用户页面添加到路由方面,我在 App_Start 处循环浏览页面并将它们显式添加到 RoutesTable。这工作正常,我们已将 AppPool 刷新设置为足够长的时间以使其成为每天一次的任务。不过,这确实让我们有 24 小时的周转时间来为我们的用户“让页面上线”,而我正在努力解决这个问题。

理想情况下,我想做的是在用户注册后将相关路由动态添加到 RouteTable。我试过这样做:

RouteTable.Routes.Add(
    RouteTable.Routes.MapRoute(
        toAdd.UrlSlug + "Homepage", 
        toAdd.UrlSlug, 
        new { controller = "Controller", View = "View", urlSlug = toAdd.UrlSlug }
    )
);

但这似乎不起作用。我在其他任何地方都找不到解决方案,而且我确信我的代码既非常幼稚,又暴露出对路由缺乏了解 - 请帮助!

【问题讨论】:

  • 我已经解决了这个问题,但不要立即提交代码,并且不确定回答我自己问题的礼仪!如果有人可以就后半部分提出建议,我很乐意让人们知道我是如何修复它的 :)
  • 回答您自己的问题并将其标记为正确是有效的。老问题,但如果可能的话,你能发布你的解决方案吗?既是为了完整性,也是为了我有完全相同的问题:)

标签: asp.net-mvc routing routetable


【解决方案1】:

如果你尝试这个,使用路由约束。获取所有用户的列表并限制所选路由以匹配该列表中的条目

public class UserPageConstraint : IRouteConstraint
{
    public static IList<string> UserPageNames = (Container.ResolveShared<IUserService>()).GetUserPageNames();

    bool _IsUserPage;
    public UserPageConstraint(bool IsUserPage)
    {
        _IsUserPage = IsUserPage;            
    }

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (_IsUserPage)
            return UserPageNames.Contains(values[parameterName].ToString().ToLower());
        else
            return !UserPageNames.Contains(values[parameterName].ToString().ToLower());
    }
}

然后在 Global.asax.cs 中为用户设置路由如下:

routes.MapRoute("UserHome", "{userPage}", new { controller = "UserPageController", action = "Index" }, new { userPage = new UserPageConstraint(true) });

对于上述路由,在 UserPageController 的 action 'index' 中,我们将 userPage 作为参数。

对于其他相对于 userPage Home 的路由,我们可以相应地添加路由。比如userdetails页面路由可以添加如下:

routes.MapRoute("UserHome", "{userPage}/mydetails", new { controller = "UserPageController", action = "Details" }, new { userPage = new UserPageConstraint(true) });

你可以试试这个看看。

【讨论】:

  • 非常有用。设法让它与类似的场景一起工作,我想要一个动态的“页面”控制器,其中包含从数据库加载的内容,用于 CMS 用例。
  • 例如很多。
【解决方案2】:

我最近也意识到了这一点,而不是动态添加路由,我不确定是否可以在不使用 Route Magic 等外部库的情况下这样做 .我相信,如果您正确设计您的架构,那么您可能只需要路由约束。由于我的应用程序很小,我只使用一个已实现的控制器并动态创建其余的控制器(目前是实验性的,但它应该可以工作)。

考虑以下路线

routes.MapRoute(
  name: "ContactRequests_Operations",
  url: "ContactRequests-{operation}",
  defaults: new { controller = "Content", action = "Module_Direct", id =  "ContactRequests" , operation = "Get" }
  );

 routes.MapRoute(
    name: "Messages",
    url: "Messages",
    defaults: new { controller = "Content", action = "Direct", id ="Messages" }
);

【讨论】:

    【解决方案3】:

    我认为你不能动态添加路由。

    看看这个问题,也许对你有帮助: ASP.NET MVC custom routing for search

    【讨论】:

    • 嗯,我开始认为这可能是真的 - 通过代码调试,看起来 RouteTable.Routes.Add() 成功增加了路由的数量,但显然只针对那个请求周期.它似乎没有将其持久化到整个应用程序使用的 RouteTable。
    • @jsidnell - 我记得有人要求动态创建区域(归结为新路线),答案是“不支持”。对于我的多租户应用程序,我最终使用 slug 和自定义 mvc 处理程序创建了通用路由来获取 slug 的值
    猜你喜欢
    • 1970-01-01
    • 2013-06-14
    • 2018-11-01
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多