YuriG
YuriG

Reputation: 368

Different landing page with MVC 4

I'm using MVC 4 and having problems with the landing page.
I have two kinds of users (let's call the FooUser and BarUser)
Each of the users has it's own landing page:
Foo/Index and Bar/Index
Once user logs in, I can identify whether he is Foo or Bar and redirect him to the relevant page.
But I still have a problem and that is when a user opens the main page. In this case the user doesn't perform a login action (since he is logged in from the previous session) so I can't redirect him to the relevant page.
Is there a way to set conditional defaults? something like:
(Any other ideas are most welcome)

if (IsCurrentUserFooUser()) //Have no idea how to get the current user at this point in the code
{
    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Foo", action = "Index", id = UrlParameter.Optional });
}
else
{
    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Bar", action = "Index", id = UrlParameter.Optional });
}

Upvotes: 1

Views: 3749

Answers (1)

webnoob
webnoob

Reputation: 15934

It might be worth considering if you really need a new controller for different users. Why not just return a different view and do some logic in the controller. This would be my preferred route as it's less overhead then dynamically calculating routes.

Routes are mapped when the application starts so it won't be able to do conditional ones. You could use a dynamic routes which are processed per request so you can do some logic to see if that route matches.

Note: return null at any point in the dynamic route to cancel it and make it invalid for that request.

public class UserRoute: Route
{
    public UserRoute()
        : base("{controller}/{action}/{id}", new MvcRouteHandler())
    {
    }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var rd = base.GetRouteData(httpContext);
        if (rd == null)
        {
            return null;
        }

        //You have access to HttpContext here as it's part of the request 
        //so this should be possible using whatever you need to auth the user. 
        //I.e session etc.
        if (httpContext.Current.Session["someSession"] == "something") 
        {
            rd.Values["controller"] = "Foo"; //Controller for this user
            rd.Values["action"] = "Index";
        }
        else
        {
            rd.Values["controller"] = "Bar"; //Controller for a different user.
            rd.Values["action"] = "Index";
        }

        rd.Values["id"] = rd.Values["id"]; //Pass the Id that came with the request. 

        return rd;
    }
}

This could then be used like this:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.Add("UserRoute", new UserRoute());

    //Default route for other things
    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

Upvotes: 2

Related Questions