【问题标题】:How can I have two views with the same route in ASP.NET MVC?如何在 ASP.NET MVC 中有两个具有相同路由的视图?
【发布时间】:2011-10-16 08:35:57
【问题描述】:

首先,我看到了这个问题:ASP.NET MVC one route, two different views,但它没有回答我的确切问题。

我想要一个视图,但根据您是否登录,使用相同的 url/路由。

我想要它,所以如果用户去: mydomain.com 然后他们将被带到营销登陆页面,或者他们将被带到用户登录的仪表板。

我上面发布的问题建议我应该使用:

if (Request.IsAuthenticated) {
    return View("Dashboard");
} else {
    return View("Index");
}

但是,我的一个视图要求我完成它们的特定操作,因为它需要该操作提供的视图模型数据。

现在,如果我这样做:

if (Request.IsAuthenticated) {
    return RedirectToAction("Index", "Dashboard");
} else {
    return View("Index");
}

这可行,但重定向会导致用户的 url 成为仪表板索引操作的路由,即 mydomain.com/dashboard。

我怎样才能既完成操作又保持我的域的根 URL?

【问题讨论】:

    标签: asp.net-mvc routing


    【解决方案1】:

    您需要在当前操作中填充模型数据

    if (Request.IsAuthenticated) {
        // populate your model to send it to the Dashboard.
        // to keep it DRY, you'll want to use a data service.
        var model = DataService.GetData();
        return View("Dashboard", model);
    } else {
        return View("Index");
    }
    

    【讨论】:

    • 那我有代码重复。它们位于两个不同的控制器中(“Dashboard”与“Landing”),并且仪表板控制器有很多对着陆控制器来说没有意义的存储库。
    • 我可能是错的,但这是我能想到的唯一方法来维护 url 并仍然检索模型。另一种(未经测试的)可能有效的方法是在“仪表板”视图中的代码块内进行模型检索,但我不建议这样做,因为您“应该”保持视图精简。
    • 为什么不能构建一个服务来完成所有繁重的工作,然后在LandingPage 操作和Dashboard 操作中使用该服务?
    • 我想这将是最好的方法。我不知道我是否可以做任何路由魔术来实现这一点。
    【解决方案2】:

    我知道这并不完全是您想要的,但它会导致仪表板位于域的根目录上并且登录重定向到不同的 URL。当您考虑到您可能希望每个“授权”页面都使用此功能时,将其放在 if 语句中看起来像是一种痛苦的方式:

    在 web.config 中

    <authentication mode="Forms">
      <forms loginUrl="~/Login" timeout="15" slidingExpiration="true" />
    </authentication>
    

    然后装饰控制器:

        [Authorize]
        public ActionResult Index()
        {
           return View();
        }
    
    
        [Authorize(Roles="SysAdmin")]
        public ActionResult ManageUsers()
        {
           return View();
        }
    

    【讨论】:

      【解决方案3】:

      这是我认为可以帮助您的快速想法。 我还没有深入测试过这个

      情况看起来类似于具有相同的操作,并用 [HttpGet] 或 [HttpPost] 操作方法选择器属性装饰它们。如果与 post 匹配,则优先执行 post 下的操作,否则获取。 我会使用自定义路由约束应用相同的逻辑

      首先创建约束类

      public class IsAuthenticatedRouteConstraint : IRouteConstraint
          {
              public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
              {
                  return httpContext.Request.IsAuthenticated;
              }
          }
      

      然后,在 global.asax 中,注册两条路由。第一个优先级更高,并且具有身份验证约束,因此在用户登录时匹配。否则第二个。通过提供正确的默认值,我认为您可以获得所需的结果。

      routes.MapRoute(
                      "DefaultAuthenticated", 
                      "{controller}/{action}/{id}",
                      new { controller = "Default", action = "Dashboard", id = UrlParameter.Optional },
                      new { isAuthenticated = new IsAuthenticatedRouteConstraint()}
                  );
      
                  routes.MapRoute(
                      "Default", //Matches if not authenticated
                      "{controller}/{action}/{id}", // URL with parameters
                      new { controller = "Default", action = "Index", id = UrlParameter.Optional }
                  );
      

      P.S 这可能还需要更多配置。希望想法有所帮助

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-19
        • 1970-01-01
        • 2020-03-22
        • 2017-03-10
        相关资源
        最近更新 更多