在错误的位置搜索的视图

时间:2015-11-10 23:56:29

标签: asp.net-mvc asp.net-mvc-4

我试图了解我在MVC项目中遇到的问题。我决定在URL中隐含地支持连字符,所以我写了一个RouteHandler来执行此操作:

public class HyphenatedRouteHandler : MvcRouteHandler
{
    protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        requestContext.RouteData.Values["controller"] = ConvertDashToCamelCase(requestContext.RouteData.Values["controller"].ToString());
        requestContext.RouteData.Values["action"] = ConvertDashToCamelCase(requestContext.RouteData.Values["action"].ToString());
        return base.GetHttpHandler(requestContext);
    }
}

ConvertDashToCamelCase就像名称所暗示的那样,并转换一个字符串,如" my-controller"进入" MyController" (我并不严格意见,但这对这个问题并不重要)。

除此之外,我正在使用区域,我将它们设置为类似于此:

  • myController的
      • 情态动词
        • myController的
      • 的Json
        • myController的

为了澄清,我的控件在不同的区域中具有匹配的名称,如上例所示。以下是路线配置:

// RouteConfig.cs
var dataTokens = new RouteValueDictionary();
dataTokens["Namespaces"] = new[] {"MyCompany.MyProject.Controllers"};
dataTokens["UseNamespaceFallback"] = false;

var constraints = new RouteValueDictionary();
var routeHandler = new HyphenatedRouteHandler();

var searchRoute = new Route("search",
    new RouteValueDictionary(new { controller = "search", action = "index" }),
    constraints,
    dataTokens,
    routeHandler
);

routes.Add("Search", searchRoute);

routes.Add(
    new Route("{controller}/{action}/{id}",
        new RouteValueDictionary(new { controller = "dashboard", action = "index", id = UrlParameter.Optional }),
        constraints,
        dataTokens,
        routeHandler
    )
);

为清楚起见,以下是Visual Studio生成的标准区域注册类,并且都继承自AreaRegistration。

// ModalsAreaRegistration.cs
var dataTokens = new RouteValueDictionary();
dataTokens["Namespaces"] = new[] { "MyCompany.MyProject.Areas.Modals.Controllers" };
dataTokens["UseNamespaceFallback"] = false;

var constraints = new RouteValueDictionary();
var routeHandler = new HyphenatedRouteHandler();

context.Routes.Add("Modals_default",
    new Route("modals/{controller}/{action}/{id}",
        new RouteValueDictionary(new { action = "index", id = UrlParameter.Optional }),
        constraints,
        dataTokens,
        routeHandler
    )
);

// JsonAreaRegistration.cs
var dataTokens = new RouteValueDictionary();
dataTokens["Namespaces"] = new[] { "MyCompany.MyProject.Areas.Json.Controllers" };
dataTokens["UseNamespaceFallback"] = false;

var constraints = new RouteValueDictionary();
var routeHandler = new HyphenatedRouteHandler();

context.Routes.Add("Json_default",
    new Route("json/{controller}/{action}/{id}",
        new RouteValueDictionary(new { action = "index", id = UrlParameter.Optional }),
        constraints,
        dataTokens,
        routeHandler
    )
);

当我访问其中任何网址时:

  • 〜/我的控制器
  • 〜/模态/我的控制器
  • 〜/ JSON /我的控制器

请求被路由到预期的控制器而没有任何问题。但是,当MVC找到视图时,它总是在根~/Views目录中搜索而不是与控制器相关的区域。

我一直无法辨别为什么会这样 - 我想如果MVC能够路由到正确的区域,从那时起它也应该能够搜索正确的Views目录。

总结

当我访问JsonModals区域内的控制器的控制器操作时,MVC正在根目录~/Views目录中搜索关联的视图而不是相应的区域&# 39; s目录。 为什么会发生这种情况,我能解决吗?

1 个答案:

答案 0 :(得分:0)

我找到了一个答案,使用了一个回答不同但相似问题的线索:https://stackoverflow.com/a/6656959/1704985

我认为问题在于我使用new Route()手动创建路线,而不是通过MapRoute方法添加路线的常规系统。我怀疑MapRoute方法会在路径中添加适当的DataToken以反映当前区域。

在我的情况下,因为我手动新建路线,所以它并没有包含所有重要的数据令牌。我将区域注册课程更新为以下内容:

// ModalsAreaRegistration.cs
var dataTokens = new RouteValueDictionary();
dataTokens["Namespaces"] = new[] { "MyCompany.MyProject.Areas.Modals.Controllers" };
dataTokens["UseNamespaceFallback"] = false;
dataTokens["Area"] = "Modals";

var constraints = new RouteValueDictionary(); var routeHandler = new HyphenatedRouteHandler();

context.Routes.Add("Modals_default",
    new Route("modals/{controller}/{action}/{id}",
        new RouteValueDictionary(new { action = "index", id = UrlParameter.Optional }),
        constraints,
        dataTokens,
        routeHandler
    ) );

// JsonAreaRegistration.cs
var dataTokens = new RouteValueDictionary();
dataTokens["Namespaces"] = new[] { "MyCompany.MyProject.Areas.Json.Controllers" };
dataTokens["UseNamespaceFallback"] = false;
dataTokens["Area"] = "Json";

var constraints = new RouteValueDictionary(); var routeHandler = new HyphenatedRouteHandler();

context.Routes.Add("Json_default",
    new Route("json/{controller}/{action}/{id}",
        new RouteValueDictionary(new { action = "index", id = UrlParameter.Optional }),
        constraints,
        dataTokens,
        routeHandler
    ) );

嘿presto,问题解决了!