我有一个User实体,在各种视图中,我想基本创建一个用户主页的链接。此功能应该在不同的控制器中可用,因此我可以轻松地重定向到用户的主页。我网站中的每个用户都有一个角色;例如读者,作家,编辑,经理和管理员。理想情况下,我想尝试实现这样的目标:
在控制器中,例如
public ActionResult SomeThingHere() {
return View(User.GetHomePage());
//OR
return RedirectToROute(User.GetHomePage());
}
在View中,我也想使用相同的功能,例如:
<%= Html.ActionLink("Link to home", user.GetHomePage() %>
是否有可能在MVC中实现这样的设计?如果是这样,我应该怎么做呢?
我目前使用这样的方法,但目前仅在一个控制器中。现在我需要在其他地方使用相同的代码,我想弄清楚如何折射这个并避免重复自己?
....
private ActionResult GetHomePage(User user){
if (user.IsInRole(Role.Admin))
return RedirectToAction("Index", "Home", new { area = "Admin" });
if (user.IsInRole(Role.Editor))
// Managers also go to editor home page
return RedirectToAction("Index", "Home", new {area = "Editor"});
if (user.IsInRole(Role.Reader))
// Writer and reader share the same home page
return RedirectToAction("Index", "Home", new { area = "Reader" });
return RedirectToAction("Index", "Home");
}
...
答案 0 :(得分:1)
这样的事情怎么样:
private string GetArea(User u)
{
string area = string.empty;
if (User.IsInRole(Admin)) area = "admin";
else if (...)
return area;
}
答案 1 :(得分:0)
我建议对HtmlHelper类进行自定义扩展。我的头脑(可能有语法错误),像这样
public static class RoleLinksExtension
{
public static string RoleBasedHomePageLink(this HtmlHelper helper, string text)
{
if (user.IsInRole(Role.Admin))
return helper.ActionLink(text, "Index", "Home", new { area = "Admin" });
// other role options here
return string.Empty; // or throw exception
}
}
然后就是
<%= Html.RoleBasedHomePageLink("Link to home") %>
在你的标记中。
如果可以避免的话,你真的不想拥有一个只是重定向到其他地方的链接。
编辑:不知道为什么我之前没有想到这一点,但是如果你做需要重定向(也许如果你在去家之前需要一些功能页面),你可以扩展IPrinciple
public static class AreaHomePageExtensions
{
public static string GetArea(this IPrinciple user)
{
if (user.IsInRole(Role.Admin))
return "Admin";
// Other options here
}
}
然后你可以做
return RedirectToAction("Index", "Home", new { area = User.GetArea() });
随时随地。
答案 2 :(得分:0)
好吧,我终于想出了一个似乎有用的设计。我写了一个控制器扩展, 使用GetHomePage方法。此扩展程序也可用于您的视图。我是这样做的:
public static class UserHelperExtension {
public static string GetHomePage(this ControllerBase controller, User user) {
return = "http://" + controller.ControllerContext
.HttpContext.Request
.ServerVariables["HTTP_HOST"] + "/"
+ GetHomePage(user);
}
//need this for views
public static string GetHomePage(string httphost, User user) {
return = "http://" + httphost + "/" + GetHomePage(user});
}
private static string GetHomePage(User user) {
if (user.IsInRole(Role.Admin))
return "/Admin/Home/Index";
if (user.IsInRole(Role.Editor))
return "/Editor/Home/Index";
if (user.IsInRole(Role.Reader))
return "/Reader/Home/Index";
return "/Home/Index";
}
}
控制器中的操作方法如下所示:
using Extensions;
...
public ActionResult SomethingHere() {
return Redirect(this.GetHomePage(user));
}
...
在视图中我有这个:
...
<%@ Import Namespace="Extensions"%>
<%=UserHelperExtension.GetHomePage(Request.ServerVariables["HTTP_HOST"], user)%>
...
优点是我可以在各种控制器中轻松使用这个“GetHomePage”方法, 或者查看我的应用程序,并且逻辑在一个地方。缺点是 我宁愿让它更安全。例如,在我的orignal测试中,我可以访问RouteValues集合:
public void User_should_redirect_to_role_home(Role role,
string area, string controller, string action) {
...
var result = (RedirectToRouteResult)userController.SomeThingHere();
Assert.That(result.RouteValues["area"],
Is.EqualTo(area).IgnoreCase);
Assert.That(result.RouteValues["controller"],
Is.EqualTo(controller).IgnoreCase);
Assert.That(result.RouteValues["action"],
Is.EqualTo(action).IgnoreCase);
...
}
但是现在我正在使用一个字符串,因此它不是类型安全的,并检查RedirectResult.Url。
...
var result = (RedirectResult) userController.SomethingHere();
Assert.That(result.Url.EndsWith("/" + area + "/" + controller + "/" + action),
Is.True);
...