Jacob Krall
Jacob Krall

Reputation: 28835

Why do you need a route defined for Html.Action?

I have created an otherwise empty ASP.NET MVC 3 application with 2 controllers, HomeController and OtherController.

HomeController.cs looks like this:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}

Index.cshtml looks like this:

@Html.Action("Index", "Other")

And, of course, Othercontroller.cs:

public class OtherController : Controller
{
    [ChildActionOnly]
    public ActionResult Index()
    {
        return Content("OK!");
    }
}

So far, so good. I run the app, and it tells me everything is OK!

Now, I take the default RegisterRoutes from Global.asax.cs:

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

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

And I crumple it up, so that no routes match OtherController:

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

        routes.MapRoute("Default", "", new { controller = "Home", action = "Index" });
    }

Now, when I run the page, it crashes with this error message:

 System.InvalidOperationException: No route in the route table matches the supplied values.
Source Error:
Line 1:  @Html.Action("Index", "Other")

I specified the controller name and action name in the call to .Action. No URLs are being generated, and no requests are being made. Why does routing even need to get involved?

Upvotes: 8

Views: 4982

Answers (3)

Memet Olsen
Memet Olsen

Reputation: 4608

The solution for me was as follows:

I had the following line that was giving me an error:

@{Html.RenderAction("ActionName", "ControllerName");}

Adding a thrid parameter solved the error:

@{Html.RenderAction("ActionName", "ControllerName", new { area = string.Empty });}

Upvotes: 0

Tommy
Tommy

Reputation: 39807

I think that this blog post will help you understand a little more:

http://blogs.charteris.com/blogs/gopalk/archive/2009/01/20/how-does-asp-net-mvc-work.aspx.

Essentially, routing is involved in determining which controller to 'fire up' to handle the request and appropriate action to invoke based on the parameters that you sent and the MVCRouteHandler uses those to make a decision. Just because you tell it which controller in your action does not make it magically ignore the routing table, go straight to that controller class and bypass all the other MVC goodness that happens in the back-end. Remember, these @HTML.Action methods can take a whole lot of overloads which could influence which route in the routing table to use (think URL structure for instance).

The MVC paths are not to static content and as such, have to be parsed through the URLRoutingModule which uses the routing table to decide on what to do. Since you have no matching route - you get an error.

EDIT

In my diatribe, I did not actually address your final statement. You're right, no URL was generated, but a request to the application was generated. HTML.Action still will use routing to determine what controller, action, area, parameters to use. I think it be fair to say in simple terms that it's like generating an ActionLink and clicking it for you.

Upvotes: 4

Bryan Naegele
Bryan Naegele

Reputation: 660

Routing got involved by using Html.Action on a controller. When the engine couldn't find the "Other" HtmlHelper with an action of "Index" it defaulted to executing that path which means passing through routing. No route matched so it threw an error.

InvalidOperationException The required virtual path data cannot be found.

http://msdn.microsoft.com/en-us/library/ee721266.aspx

Upvotes: 0

Related Questions