Asp.net mvc 如何在ASP.NET MVC中拥有两个具有相同路径的视图?

Asp.net mvc 如何在ASP.NET MVC中拥有两个具有相同路径的视图?,asp.net-mvc,routing,Asp.net Mvc,Routing,首先,我看到了这个问题:但它并没有回答我的确切问题 我希望有一个视图,但具有相同的url/路由,具体取决于您是否登录 如果用户转到: mydomain.com然后,它们将被带到营销登录页,或者被带到登录仪表板的用户 我在上面发布的问题建议我应该使用: if (Request.IsAuthenticated) { return View("Dashboard"); } else { return View("Index"); } 但是,我的一个视图要求我完成它们的特定操作,因为它

首先,我看到了这个问题:但它并没有回答我的确切问题

我希望有一个视图,但具有相同的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

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

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

我知道这并不完全是你想要的,但它会导致仪表板位于域的根目录上,并将登录重定向到不同的URL。当你认为你可能想要每个授权页面的这个功能时,把它放进if语句看起来是一个痛苦的方式:

在web.config中

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

这是一个我认为可以帮助你的快速想法。我还没有对此进行深入测试

这种情况看起来类似于使用相同的操作,并使用[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 }
            );

这可能还需要更多的配置。希望这个想法有帮助

那么我有代码复制。这是在两个不同的控制器中,仪表板控制器和着陆控制器,仪表板控制器有很多对着陆控制器来说没有意义的存储库。我可能错了,但这是我能想到的维护url并仍然检索模型的唯一方法。另一种可能有效的未经测试的方法是在Dashboard视图中的代码块内进行模型检索,尽管我不建议这样做,因为您应该保持视图的精简。为什么您不能构建一个完成所有繁重工作的服务,然后在登录页面操作和仪表板操作中使用该服务?我想这是最好的方法。我不知道是否有任何路由魔术我可以做到这一点。
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 }
            );