【发布时间】:2015-11-10 23:56:29
【问题描述】:
我试图了解我在 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”(我知道不是严格的驼峰式,但这对这个问题并不重要)。
除此之外,我正在使用区域,并且我将它们设置为类似于此:
- 我的控制器
- 区域
- 模态
- 我的控制器
- JSON
- 我的控制器
- 模态
- 区域
为了澄清,我的不同区域中确实有名称匹配的控制器,如上例所示。以下是路线配置:
// 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
)
);
当我访问这些 URL 时:
- ~/我的控制器
- ~/modals/my-controller
- ~/json/my-controller
请求被路由到预期的控制器,没有任何问题。但是,当 MVC 定位视图时,它总是在根目录 ~/Views 中搜索,而不是在与控制器相关的区域中搜索。
我一直无法辨别为什么会这样——我想如果 MVC 能够路由到正确的区域,那么从那时起它也应该能够搜索正确的 Views 目录。
总结
当我访问 Json 或 Modals 区域内的控制器的控制器操作时,MVC 正在根 ~/Views 目录而不是相应区域的目录内搜索关联的视图。 为什么会发生这种情况,我可以解决它吗?
【问题讨论】: