【问题标题】:ASP.NET MVC 2 Routing with additional consistent parameters (not just controller & action)具有附加一致参数的 ASP.NET MVC 2 路由(不仅仅是控制器和操作)
【发布时间】:2011-03-20 06:40:37
【问题描述】:

目前,我的网址如下所示:

http://www.example.com/user/create
http://www.example.com/user/edit/1

但现在,我必须支持多个组织及其用户。我需要这样的东西:

http://www.example.com/org-name/user/create
http://www.example.com/org-name/user/edit/1

我无法让路由完美地工作,所以我必须在组织名称的开头添加一个标记,这样路由就不会与控制器/操作对混淆。没什么大不了的,但我的网址现在看起来像这样:

http://www.example.com/o/org-name/user/create
http://www.example.com/o/org-name/user/edit/1

没关系。我可以忍受。

这就是我遇到麻烦的地方:
当我选择组织后生成 URL 时,它不会保留组织名称。所以当我在这里时:

http://www.example.com/o/org-name

...我使用 Url.Action("User", "Create") 生成一个 URL,它输出:

/user/create

...而不是我想要的:

/o/org-name/user/create

这是我的路线的样子(按顺序):

        routes.MapRouteLowercase(
            "DefaultOrganization",
            "{token}/{organization}/{controller}/{action}/{id}",
            new { id = UrlParameter.Optional },
            new { token = "o" }
        );

        routes.MapRouteLowercase(
            "OrganizationDashboard",
            "{token}/{organization}/{controller}",
            new { controller = "Organization", action = "Dashboard" },
            new { token = "o" }
        );

        routes.MapRouteLowercase(
            "DefaultSansOrganization",
            "{controller}/{action}/{id}",
            new { controller = "Core", action="Dashboard", id = UrlParameter.Optional }
        );

类似于ASP.NET MVC Custom Routing Long Custom Route not Clicking in my Head这个问题。

我有一种感觉,这最终会很明显,但现在是星期五,现在还没有发生。


编辑:
Womp 的建议奏效了,但这是实现自动化的最佳方法吗?

public static string ActionPrepend(this UrlHelper helper, string actionName, string controllerName)
    {
        string currentUrl = helper.RequestContext.RouteData.Values["url"] as string;
        string actionUrl = string.Empty;

        if (currentUrl != null)
        {
            Uri url = new Uri(currentUrl);

            if (url.Segments.Length > 2 && url.Segments[1] == "o/")
                actionUrl = string.Format("{0}{1}{2}{3}", url.Segments[0], url.Segments[1], url.Segments[2],
                    helper.Action(actionName, controllerName));
        }

        if(string.IsNullOrEmpty(actionUrl))
            actionUrl = helper.Action(actionName, controllerName);

        return actionUrl;
    }


编辑:
修复了我的工作路线,而不是一起破解它。最终的解决方案不需要 URL 中的愚蠢 {token}。也许这对其他人有帮助:

routes.MapRouteLowercase(
    "Organization",
    "{organization}/{controller}/{action}/{id}",
    new { controller = "Organization", action = "Dashboard", id = UrlParameter.Optional },
    new { organization = @"^(?!User|Account|Report).*$" }
);

routes.MapRouteLowercase(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Core", action = "Dashboard", id = UrlParameter.Optional }
);

【问题讨论】:

  • 在这里查看我的评论:stackoverflow.com/questions/3321750/… 将组织存储在会话中而不是路径中不是更有意义吗?您将如何验证您的用户不会尝试访问其他组织?
  • 如果你问我,我首先不喜欢你的令牌解决方案。组织名称是一个参数,就像用户的 ID 一样。您正在从组织 Contoso 编辑 ID 为 1 的 John Doe。我只需在路径的末尾或中间添加组织参数,如下所示:{controller}/{action}/{organization}/{id}。我实际上会定义更具体的路由,例如创建用户/创建/{组织}或编辑用户/编辑/{组织}/{id}。无论哪种方式,只有在您使用 OrgID 和 UserID 作为复合主键时才需要在其中使用组织
  • @Ryan 我们在 Azure 上运行,所以我必须将所有会话信息保存在 cookie 中(不可怕)。我们的 API 已在每次调用时强制执行安全性,因此人们猜测其他组织名称(或在不同帐户中有重复)得到解决。
  • @mare 你是对的,token 是一个愚蠢的主意 :) 我设法修复了路线以允许我想要完成的事情!我将用我的最终解决方案更新原始问题中的代码。

标签: c# asp.net-mvc asp.net-mvc-2 routing


【解决方案1】:

Url.Action 使用路由值通过查询虚拟路径提供程序并尝试匹配最具体的路由来生成实际 URL。在您使用的形式中,您正在为控制器和操作提供值,这与大多数简单网站一样深,因此该方法的形式很方便。 Url.Action 查询路由系统时,只有一个“控制器”和一个“动作”段要匹配。

如果您向该方法提供所需的其余路由信息,它将正确匹配您想要的路由,并返回正确的 URL。试试这个:

Url.Action("User", "Create", new { token = "o", organization = "organization" })

【讨论】:

  • 啊哈,成功了!所以为了自动化这个,UrlHelper 上的扩展方法会是最好的吗?我用有效的代码编辑了上面的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-03-04
  • 2012-05-29
  • 2014-08-24
  • 2021-05-14
  • 2016-04-03
  • 1970-01-01
相关资源
最近更新 更多