【问题标题】:ASP.net MVC RenderAction and RouteASP.net MVC 渲染动作和路由
【发布时间】:2011-04-23 05:34:55
【问题描述】:

我有一个使用 ASP.net MVC3 的网络项目。我的项目中有一个子动作。我用

<% Html.RenderAction("Navigator", "Application");%>

调用共享操作。但我发现如果我当前的 url 是“localhost/application”,它会抛出异常“路由表中的路由与提供的值不匹配”。但是当当前 url 是“localhost/application/index”时,它可以正常工作。索引是我的路由配置中的默认操作,如下所示:

    public static void RegisterRoutesTo(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });
        //routes.IgnoreRoute("{*chartName}", new { chartName = @"(.*)?Chart.aspx" }); //ignore request for charting request
        routes.Ignore("{*pathInfo}", new { pathInfo = @"^.*(ChartImg.axd)$" });

        routes.MapRoute(
            "Default",                                              // Route name
            "{controller}/{id}/{action}",                          // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional },  // Parameter defaults
            new { httpMethod = new HttpMethodConstraint("GET", "POST") }   // Allowed http methods
        );
    }

请注意,我切换了默认 ID 和操作位置。我看到 mvc 可以在使用“Html.ActionLink(...)”时删除 url 中的默认控制器和操作名称。而且我不喜欢在我的视图中使用显式的 url 字符串。如何让它发挥作用?

我的动作代码很简单:

    [ChildActionOnly]
    public ActionResult Navigator()
    {
        return PartialView(appFacility.GetAll());
    }

非常感谢。

【问题讨论】:

    标签: asp.net-mvc-3


    【解决方案1】:

    错误的路由 URL 定义和默认值组合

    问题是可选参数后面不能有非可选参数。

    为什么localhost/application/index 有效?这是路由值:

    • 控制器 = "application"(从 URL 提供)
    • id = "index"(由 URL 提供)
    • action = "Index"(作为默认路由提供)

    这些值基本上等于 localhost/application/index/index 请求 URL。

    如果你想让你的RenderAction 工作,你必须这样称呼它:

    <% Html.RenderAction("Navigator", "Application", new { id = 0 }); %>
    

    等于localhost/application/0/navigator 请求网址。

    但是你很快就会发现你的路由不起作用并且你必须改变它(因为我想你不喜欢在你的 URL 中有那个额外的 0)。如果您提供信息,您希望您的路线工作方式(或您决定切换action 和id 的原因),我们可以提供有助于满足您要求的答案。

    【讨论】:

    • 谢谢罗伯特,我认为是可选参数的问题。关于网址,这是我们团队的偏好。我们更喜欢 /book/{id}/view 而不是 /book/view/{id}。 ASFAIK,Stackoverflow 是用 asp.net mvc 构建的,url 类似于“question/ask”和“question/12345/edit”。我认为它更“RESTful”。我之所以这么说,是因为我的富 UI 项目中有很多安静的动作。为了解决这个问题,我添加了另一个路由图:“{controller}/{action}/{id}”,将 id 设为可选,并将“{controller}/{id}/{action}”中的 id 设为必需。我不知道它是否正确,但现在可以正常工作。
    【解决方案2】:

    可选参数仅在路径结束时才能正常工作。试试这样的:

    routes.MapRoute("DefaultWithID", "{controller}/{id}/{action}",
        new { action = "Index" },
        new { id = "^[0-9]+$" }
    );
    
    routes.MapRoute("Default", "{controller}/{action}",
        new { controller = "Home", action = "Index" }
    );
    

    编辑:希望已修复 :) 这个版本依赖于 ID 将是数字的事实 - 没有约束,我们无法判断它是指操作还是 id,因此当指定 ID 时,路由不会有默认操作

    【讨论】:

    • 我认为这行不通,因为第一个路由也将匹配第二个路由的请求。它只会路由到Index 操作,并附带一些id。基本上第二条路线永远不会被击中。
    • 好的,我编辑了我的答案。在路由开始或中间设置可选参数的唯一方法是使用 2 条路由并限制其中之一
    • 谢谢 Lukas,我很喜欢你的方式。为非 id 请求添加默认地图路由
    猜你喜欢
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 2019-04-25
    相关资源
    最近更新 更多