我试图了解我在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" (我并不严格意见,但这对这个问题并不重要)。
除此之外,我正在使用区域,我将它们设置为类似于此:
为了澄清,我的控件在不同的区域中具有匹配的名称,如上例所示。以下是路线配置:
// 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
)
);
当我访问其中任何网址时:
请求被路由到预期的控制器而没有任何问题。但是,当MVC找到视图时,它总是在根~/Views
目录中搜索而不是与控制器相关的区域。
我一直无法辨别为什么会这样 - 我想如果MVC能够路由到正确的区域,从那时起它也应该能够搜索正确的Views目录。
总结
当我访问Json
或Modals
区域内的控制器的控制器操作时,MVC正在根目录~/Views
目录中搜索关联的视图而不是相应的区域&# 39; s目录。 为什么会发生这种情况,我能解决吗?
答案 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,问题解决了!