【问题标题】:UrlHelper.Action doesn't map to the area that the controller is in correctlyUrlHelper.Action 未正确映射到控制器所在的区域
【发布时间】:2011-03-25 05:33:49
【问题描述】:

更新 2

好的 - 所以看起来我的问题再次略有变化:-)

我现在意识到 UrlHelper.Action 似乎无法正确解析任何区域中的 URL,除非明确指定区域名称。如果未指定,它似乎会返回我们当前所在的任何区域名称,这使它看起来像是在站点的一个部分工作,但另一个区域中的相同链接解析为错误的区域名称。

要么我做了一些时髦的事情来让它做到这一点,要么我不太理解这个 Action 方法是如何工作的。

更新 1

我可以通过以下方式完成这项工作:

return helper.Action("add", "product",new {area = "storemanagement"});

这稍微改变了我的问题。

为什么 MVC 路由不能消除同名控制器的歧义并解析为指定操作方法的控制器?

原创帖子

大家好,

我在 UrlHelper 类上创建了一个辅助方法,但其中一个路由存在小问题。

以下是相关帮助方法的代码:

public static string AddProduct(this UrlHelper helper)
        {
            return helper.Action("add", "product");
        }

我基本上有两个名为“product”的控制器,它们位于站点的不同区域。其中一个用于产品浏览,另一个用于产品管理。只有一个产品控制器包含“添加”操作方法。

当我输出 AddProduct 的值时

<%: Url.AddProduct() %>

区域名称解析为我正在浏览的当前区域,而不是包含 Add 操作方法的产品控制器的正确区域。

我需要在路线中设置什么吗?我不确定路由如何与 UrlHelper.Action 一起使用,所以我不知道是否可以做我正在尝试的事情。

为任何帮助干杯。

【问题讨论】:

  • 尝试使用此方法添加控制器和区域名称作为附加参数 sig UrlHelper.Action Method (String, String, Object)
  • 谢谢艾哈迈德。这实际上确实有效,所以我将其添加为我的问题的更新。我仍然对为什么路由系统没有消除两个控制器的歧义感兴趣,而是似乎放弃并假设使用当前区域。
  • 要回答您的问题,需要深入挖掘 MVC 框架的内部结构以找出发生这种情况的原因。无论如何,据我所见,只有controlleraction 路由值有特殊处理,即根据您从哪里调用助手来推断/假设区域。因此需要指定面积参数。

标签: c# asp.net asp.net-mvc-2 asp.net-mvc-routing


【解决方案1】:

只是为了清楚起见将答案放在答案部分......

无论何时使用UrlHelper.Action 生成链接路径,都需要将Area 添加到RouteValues

如果你在Controller中,你可以像这样stub a UrlHelper

var httpContext = new HttpContextWrapper(System.Web.HttpContext.Current);
var requestContext = new RequestContext(httpContext, new RouteData());
var urlHelper = new UrlHelper(requestContext);

你总是可以像这样get the current area

HttpContext.Current.Request.RequestContext.RouteData.DataTokens["area"]

最后,当像这样使用UrlHelper pass the area in the RouteValues object 时:

var url = urlHelper.Action("Index", "Home", new { area = "Pages" }));

【讨论】:

    【解决方案2】:

    这是 ASP.NET 路由的默认行为。

    在“区域”中时,通过控制器和默认位置的操作名称搜索操作(和视图)。 除非在操作中另有说明,否则该视图被假定为 ActionName,例如return PartialView("_MyPartialView.cshtml", ViewModel)

    默认位置如下:{Controller} = 控制器名称,{Area} = 区域名称

    控制器:

    "Areas/{Area}/{Controller}/"
    "Controllers/{Controller}"
    

    观看次数:

    "Areas/{Area}/Views/{Controller}/" 
    "Areas/{Area}/Views/Shared/"
    "Views/Shared"
    

    如果您不在路线值中提供区域,它将永远不会在这些位置之外进行搜索。该区域与您呼叫助手的位置相同。如果您在根级别(不在区域中),它将被限制为

    "Controllers/{Controller}" // controller
    "Views/{Controller}/" // views
    "Views/Shared" // views
    

    问题是当你在一个 Area1 中搜索时 "Areas/Area1/{Controller}/",当您在 Area2 中时,它搜索了 "Areas/Area2/{Controller}/"(并且都搜索了 Controllers/ProductControllers/Shared)。当您在正确的区域中时它能够找到它,因为它适合默认搜索位置,但在另一个区域中时却找不到,因为控制器仅在一个物理区域中。

    像你一样添加区域,告诉它在预定义的区域中搜索,这样它就会直接去那里。 "Areas/Storemanagement/Views/product/" 并搜索添加操作中定义的视图。

    让一个空的帮助方法返回一个 Url.Action 方法没有什么意义,但这也许只是为了演示。

    (我只是注意到这个问题很老了,但我想这可以在这里供将来参考)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-02
      • 1970-01-01
      • 2014-09-24
      • 2023-04-03
      • 2019-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多