【发布时间】: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