How can I have two views with the same route in ASP.NET MVC?
To start out, I have seen this question: ASP.NET MVC one route, two different views but it doesn't answer my exact question.
I want to have one view but with the same url/route depending on whether or not you are logged in.
I want it so if a user goes to: mydomain.com then they will either be taken to the marketing landing page or they will be taken to the users logged-in dashboard.
The question I posted above suggests that I should use:
if (Request.IsAuthenticated) {
return View("Dashboard");
} else {
return View("Index");
}
However, one of my views requires that I go through their particular actions because it requires the view model data that the action provides.
Now, if I do this:
if (Request.IsAuthenticated) {
return RedirectToAction("Index", "Dashboard");
} else {
return View("Index");
}
This works, but the redirect will cause the user's url to be the route for the dashboard-index action which is mydomain.com/dashboard.
How can I both go through the action an开发者_运维问答d still maintain the root url for my domain?
You'll want to populate the model data in your current action
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");
}
I know this is not exactly what you want but it results in the Dashboard being on the root of the domain and login redirecting to a different URL instead. And when you consider that you will probably want this functionality for every "Authorised" page putting it in an if statement looks like a painful way to go about it:
In web.config
<authentication mode="Forms">
<forms loginUrl="~/Login" timeout="15" slidingExpiration="true" />
</authentication>
then Decorate controllers:
[Authorize]
public ActionResult Index()
{
return View();
}
[Authorize(Roles="SysAdmin")]
public ActionResult ManageUsers()
{
return View();
}
This is the quick idea which i think can help you. I haven't tested this in depth
Situation looks similar to having same action, and decorating them with [HttpGet] or [HttpPost] action method selector attributes. If there's match with post, it takes priority and action under post is executed, else get. I would apply the same logic with using custom route constraint
First create the constraint class
public class IsAuthenticatedRouteConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
return httpContext.Request.IsAuthenticated;
}
}
Then, in global.asax, register two routes. First one is higher priority and has the authenticated constraint, so it is matched when user is logged on. Else the second one. By giving correct default values, i think you could get the desired results.
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 this may still need more configuration. Hope idea helps
精彩评论