代码之家  ›  专栏  ›  技术社区  ›  Dai Bok

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

  •  2
  • Dai Bok  · 技术社区  · 14 年前

    例如,在控制器中

    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");
    }
    ...
    
    3 回复  |  直到 7 年前
        1
  •  1
  •   No Refunds No Returns    14 年前

    private string GetArea(User u)
    {
       string area = string.empty;
       if (User.IsInRole(Admin)) area = "admin";
       else if (...)
    
    
       return area;
    }
    
        2
  •  0
  •   pdr    14 年前

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

    随便什么时候都行。

        3
  •  0
  •   Dai Bok    14 年前

    使用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”方法, 或者查看我的应用程序,逻辑就在一个地方。缺点是

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