0
votes

I have a custom RouteBase, MyRoute which I want to work for an area "MyArea" which contains code like:

public override GetRouteData(HttpContextBase httpContext)
{
    var result = new RouteData(this, new MvcRouteHandler());

    result.Values.Add("area", "MyArea");
    result.Values.Add("controller", "MyController");
    result.Values.Add("action", "Index");
}

I register this in the MyAreaAreaRegistration.cs file:

public override string AreaName { get { return "MyArea"; } }

public override void RegisterArea(AreaRegistrationContext context)
{
    context.Routes.Add(new MyRoute());

    // other routes
    context.MapRoute(/* ... */);
}

and when making requests, it successfully calls the Index action on MyController:

public ActionResult Index()
{
    return this.View();
}

However, MVC doesn't search in the correct folders for the view:

The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/MyController/Index.aspx
~/Views/MyController/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/MyController/Index.cshtml
~/Views/MyController/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml

when the view is located in

~/Areas/MyArea/Views/MyController/Index.cshtml

How can I make MVC search in the correct area?

1

1 Answers

0
votes

If you look at the source for AreaRegistrationContext.MapRoute you can see that it treats the area differently to the other route variables:

public Route MapRoute(string name, string url, object defaults, object constraints, string[] namespaces)
{
    if (namespaces == null && this.Namespaces != null)
    {
        namespaces = this.Namespaces.ToArray<string>();
    }
    Route route = this.Routes.MapRoute(name, url, defaults, constraints, namespaces);
    route.DataTokens["area"] = this.AreaName; // *** HERE! ***
    bool flag = namespaces == null || namespaces.Length == 0;
    route.DataTokens["UseNamespaceFallback"] = flag;
    return route;
}

where this.AreaName is populated from the AreaRegistration.

So a quick fix for the problem is to replace the call:

result.Values.Add("area", "MyArea");

with

result.DataTokens["area"] = "MyArea";