Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make sure controller and action exists before doing redirect, asp.net mvc3

In one of my controller+action pair, I am getting the values of another controller and action as strings from somewhere and I want to redirect my current action. Before making a redirect I want to make sure that controller+action exists in my app, if not then redirect to 404. I am looking for a way to do this.

public ActionResult MyTestAction()
{
    string controller = getFromSomewhere();
    string action = getFromSomewhereToo();

    /*
      At this point use reflection and make sure action and controller exists
      else redirect to error 404
    */ 

    return RedirectToRoute(new { action = action, controller = controller });
}

All I have done is this, but it doesn't work.

var cont = Assembly.GetExecutingAssembly().GetType(controller);
if (cont != null && cont.GetMethod(action) != null)
{ 
    // controller and action pair is valid
}
else
{ 
    // controller and action pair is invalid
}
like image 991
Rusi Nova Avatar asked Aug 11 '11 21:08

Rusi Nova


1 Answers

You can implement IRouteConstraint and use it in your route table.

The implementation of this route constraint can than use reflection to check if controller/action exists. If it doesn't exist the route will be skipped. As a last route in your route table, you can set one that catches all and map it to action that renders 404 view.

Here's some code snippet to help you started:

public class MyRouteConstraint : IRouteConstraint
    {
        public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
        {

            var action = values["action"] as string;
            var controller = values["controller"] as string;

            var controllerFullName = string.Format("MvcApplication1.Controllers.{0}Controller", controller);

            var cont = Assembly.GetExecutingAssembly().GetType(controllerFullName);

            return cont != null && cont.GetMethod(action) != null;
        }
    }

Note that you need to use fully-qualified name of the controller.

RouteConfig.cs

routes.MapRoute(
                "Home", // Route name
                "{controller}/{action}", // URL with parameters
                new { controller = "Home", action = "Index" }, // Parameter defaults
                new { action = new MyRouteConstraint() } //Route constraints
            );

routes.MapRoute(
                "PageNotFound", // Route name
                "{*catchall}", // URL with parameters
                new { controller = "Home", action = "PageNotFound" } // Parameter defaults
            );
like image 152
frennky Avatar answered Oct 04 '22 15:10

frennky