从不同的控制器重定向到相同的 ActionResult

发布于 2024-08-21 16:20:10 字数 1086 浏览 7 评论 0原文

我有一个用户实体,在各种视图中,我基本上想创建指向用户主页的链接。此功能应该在不同的控制器中可用,因此我可以轻松重定向到用户的主页。我网站中的每个用户都有一个角色;例如读者、作家、编辑、经理和管理员。理想情况下,我想尝试实现这样的东西:

在控制器中,例如

public ActionResult SomeThingHere() {
    return View(User.GetHomePage());
//OR 
    return RedirectToROute(User.GetHomePage());
}

在视图中,我也想使用相同的功能,例如:

<%= 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");
}
...

I have a User entity, and in various views, I want to create links to a user home page basically. This functionality should be available in different controllers, so I can easily redirect to the user's home page. Each user in my site has a role ; for example reader, writer, editor, manager and admin. Ideally, I want to try to achieve something like this:

In a controller, for example

public ActionResult SomeThingHere() {
    return View(User.GetHomePage());
//OR 
    return RedirectToROute(User.GetHomePage());
}

in a View, I also want to use the same functionality, for example:

<%= Html.ActionLink("Link to home", user.GetHomePage() %>

Is it possible to achieve such a design in MVC? If so , how should I go about it?

I currently use a method like this, but it is only in one controller at the moment. Now I need to use the same code somewhere else and I am trying to figure out how I could refractor this and avoid repeating myself?

....
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");
}
...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

堇年纸鸢 2024-08-28 16:20:10

像这样的事情怎么样:

private string GetArea(User u)
{
   string area = string.empty;
   if (User.IsInRole(Admin)) area = "admin";
   else if (...)


   return area;
}

How about something like this:

private string GetArea(User u)
{
   string area = string.empty;
   if (User.IsInRole(Admin)) area = "admin";
   else if (...)


   return area;
}
余生再见 2024-08-28 16:20:10

我建议对 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() });

您可以随时

I would suggest a custom extension to the HtmlHelper class. Top of my head (liable to have syntax errors), something like this

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
    }
}

Then it's just

<%= Html.RoleBasedHomePageLink("Link to home") %>

in your markup.

You don't really want to have a link to somewhere that simply redirects somewhere else, if you can avoid it.

Edit: No idea why I didn't think of this earlier, but if you do need to redirect (perhaps if you need some functionality before going to the home page), you could extend IPrinciple instead

public static class AreaHomePageExtensions
{
    public static string GetArea(this IPrinciple user)
    {
        if (user.IsInRole(Role.Admin))
            return "Admin";
        // Other options here
    }
}

Then you can do

return RedirectToAction("Index", "Home", new { area = User.GetArea() });

whenever you like.

留一抹残留的笑 2024-08-28 16:20:10

好吧,我终于想出了一个似乎可行的设计。我写了一个控制器扩展,
使用 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”方法,
或视图贯穿我的应用程序,并且逻辑位于一处。缺点是
我希望它的类型更加安全。例如,在我的原始测试中,我可以访问 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);
...

Well I finally came up with a design that seems to work. I have written an controller extension,
with a GetHomePage Method. This extension can also be used in your views. Here is how I did It:

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";
    }
}

The action method in the controller looks like this:

    using Extensions;
...
public ActionResult SomethingHere() {
    return Redirect(this.GetHomePage(user));
}
...

In the view I have this:

...
<%@ Import Namespace="Extensions"%>
<%=UserHelperExtension.GetHomePage(Request.ServerVariables["HTTP_HOST"], user)%>
...

The advantage is that I can easily use this "GetHomePage" method in various controllers,
or views thoughout my application, and the logic is in one place. The disadvantage is that
I would have preferred to have it more type safe. For example, in my orignal tests, I had access to RouteValues collection:

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);
...

}

But now that I am using a string so it is not type safe, and checking the RedirectResult.Url.

...
var result = (RedirectResult) userController.SomethingHere();
Assert.That(result.Url.EndsWith("/" + area + "/" + controller + "/" + action), 
    Is.True);
...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文