views:

128

answers:

3

Hi everyone!

How can I do this: I have on page named "Schedule" and it can be accessed through 2 differente ways:

URL 1- www.bla.com/Admin/Schedule
URL 2- www.bla.com/Schedule

"URL 1" will be accessed by users with Admin previlegies and this View will show some Admin stuff, and users must be LoggedOn.

In the otherhand, "URL 2" will be accessed by users NOT LoggedOn and it will NOT show the admin stuff.

But, they are the same page, just with some differences depending on user's access.

I already have AdminController and I intend to put this "Schedule" View as part of this controller. As result, I know if I type "URL 1" it will work. But, if I type "URL 2"? Will I have to create a "ScheduleController" just to handle this?

I wonder if there is a way to resolve this by Global.asax, configuring the routing... I don't know...

Thanks!!!

A: 

Sounds like you don't really need a different URL if it's the same page. However if for some reason you still want to use 2 different URLs...

Url 1:

routes.MapRoute("ScheduleAdmin", "Admin/Schedule",
                new
                {
                    controller = "AdminController",
                    action = "Schedule"
                });

Url 2:

routes.MapRoute("Schedule", "Schedule",
                new
                {
                    controller = "ScheduleController",
                    action = "Index"
                });

You didn't make it clear what action you were using for the schedule controller so feel free to change that.

Chad Moran
I understood what you've said, but I really nedd to have theses 2 URLs... is there a way??
AndreMiranda
Chad, looking your explanation, I will have to create a ScheduleController, right? What I was intending to do is to create an ActionResult named "Schedule" in my AdminController. And this Action will be rendered the way I've said in my question, configuring Global.asax... I think it's not possible
AndreMiranda
+1  A: 

Make the View shared and just render it from both controller actions. Pass the appropriate data via the model (or ViewData) so the View knows not to render the admin stuff when rendered from the non-admin controller action.

And, yes, create the Schedule controller. Make the routing simple and handle sharing the generation code on the back end.

AdminController

public ActionResult Schedule( ... )
{
    Schedule sched = ... get model ...

    return View("Schedule", new SchedViewModel {
                                                 Schedule = sched,
                                                 Admin = true 
                                               } );
}

ScheduleController

public ActionResult Index( ... )
{
    Schedule sched = ... get model ...

    return View("Schedule", new SchedViewModel {
                                                 Schedule = sched,
                                                 Admin = false 
                                               } );    }
tvanfosson
+1  A: 

You can map the /Schedule route to the /Admin/Schedule action from the Global.asax.cs like this:

        routes.MapRoute(
            "Schedule",
            "schedule",
            new { controller = "Admin", action = "Schedule" }
        );

This will solve your immediate problem of wanting two separate routes resulting in the same action/view.

However, this will not solve your scenario properly. The main issue is that the identity of the logged on user is orthogonal to the route the request takes. In other words, you can't force the admin user to always hit the /Admin/Schedule route, they could just as well hit the /Schedule route and still would expect the same end result. Not only that, but doing it this way will prevent you from using the [Authorize] attribute on the Admin controller or the action to force the user to login and will have to implement custom logic checking which route the action was hit through and decide whether you want to force login or let the user through.

Thus, you have to make a decision:

  • you share the controller, action and the view and determine whether to show the additional information in the view based on the identity and the role membership of the logged on user (if any). You will have to change the name of the controller then, as /Admin will not reflect the new role this class has;
  • you share only the view and have two separate controllers and actions - Admin.Schedule and User.Schedule. You will have to put the view in the /views/shared folder and return the same view fromboth actions, potentially passing different model. You'll end up with two routes - /Admin/Schedule and /User/Schedule;
  • you have two separate controllers, actions and views.

In all three cases, you can still have the rule above pointing to the appropriate controller, if you want to have also the shortest /Schedule route.

Franci Penov