【问题标题】:Views being searched for in the wrong location在错误位置搜索视图
【发布时间】: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 目录。

总结

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

【问题讨论】:

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


    【解决方案1】:

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

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

    在我的例子中,因为我手动更新了 Route,它没有包含所有重要的数据令牌。我将我的地区注册课程更新为以下内容:

    // 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
        ) );
    

    你好,问题解决了!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      相关资源
      最近更新 更多