【问题标题】:MVC weird routing behaviourMVC 奇怪的路由行为
【发布时间】:2016-09-25 13:57:17
【问题描述】:

我对 MVC 中的某些路由有一个奇怪的问题。这是我的场景:

  1. 用户在访问该网站后会显示在首页:testproject.com:57416/Home
  2. 用户在左侧有一个菜单,菜单项为“解决方案”。
  3. 用户按下菜单项“解决方案”,菜单项展开,显示 5 个子项。
  4. 用户按下子项“Demo”,重定向到testproject.com:57416/Solutions/SetLayout?layoutString=page1%7Csize15
  5. 定义参数 layoutString 后,网格 (DevExpress) 知道如何过滤要显示的数据。
  6. 网格呈现给用户,他现在可以在网格中导航,操作布局。
  7. 用户现在想再次看到干净的演示布局,并且(s)他按下菜单项“解决方案”-> 子项“演示”。
  8. 在这种情况下,动作ActionResult SetLayout(string layoutString) 没有被命中,而是动作ActionResult Index() 被命中,因此没有将布局设置为layoutString 没有作为参数发送
  9. 用户被重定向到的 url,如下所示:testproejct.com:57416/Solutions?undefined=undefined

这可能读起来有点累,但这是我解释我的场景的最佳方式,因为我以前在 MVC 中从未见过这样的事情。我真的不知道发生了什么,以及为什么动作ActionResult SetLayout(string layoutString) 没有被第二次击中。

我想我应该展示一些代码,以便我们缩小可能性。

_Layout.cshtml有菜单项

<li class="has-submenu">
    <a href ="#" class="navigation-submenu-toggler show-solution-views">Solutions</a>

    <ul class="nav sub-menu-list">
        <li>
            @Html.ActionLink("Demos", "SetLayout", "Solutions", new { layoutString = "page1|size15" }, null)
        </li>
    </ul>
</li>

ActionResult SetLayout(string layoutString)

public ActionResult SetLayout(string layoutString)
{
    Session["Layout"] = layoutString;
    return RedirectToAction("Index", "Solutions");
}

ActionResult Index()

public ActionResult Index ()
{
    using(var db = new DataBasecontext())
    {
        var list = db.Solutions.ToList();
        return View(list);
    }
}

编辑

我发现只有当我在同一个控制器中时才会发生这种情况。持有动作ActionResult SetLayout(string layoutString) 的控制器是SolutionsController。如果我来自,假设AccountController 一切正常,但从SolutionsController 更改为SolutionsController 中的另一个操作不起作用。

想一想,这可能与我的地图路线有关吗?

routes.MapRoute(
    name: "ControllerIdActionId",
    url: "{controller}/{id}/{action}/{id2}",
    default : new { id2 = UrlParameter.Optional }
);

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    default : new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

routes.MapRoute(
    name: "Solutions",
    url: "{controller}/{id}/{action}",
    default : new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

【问题讨论】:

  • @SometimesCode 已经有了,忘记放了。已更正
  • 查看Why map special routes first before common routes in asp.net mvc 了解发生这种情况的原因以及可能的解决方法列表。在这里可以说您的路由配置错误。 RouteLink 是解决该问题的一种解决方法(不是解决方案),因为传入的请求与您想要的路由不匹配,并且您的路由表中有无法访问的执行路径。

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


【解决方案1】:

似乎 layoutString 参数在第二次触发时缺少参数值,因此将空字符串值插入 Session 键(并且与该 Session 相关的 Javascript 函数将空字符串视为未定义)。

public ActionResult SetLayout(String layoutString)
{
    // Test if the string is null or empty before filling session key,
    // if it is empty one, leave the session key as is
    if (!String.IsNullOrEmpty(layoutString)) {
         Session["Layout"] = layoutString; 
    }
    return RedirectToAction("Index", "Solutions");
}

也许这不是最好的方法,我只是从 SetLayout 方法的角度来看,用正确的查询字符串填充 Session 键。

【讨论】:

  • 我知道这将解决与 layoutString 为空相关的任何问题。我不明白为什么它是空的?
【解决方案2】:

在您的操作链接中将第 5 个参数作为 null 传递,如下所示:

@Html.ActionLink("Demos", "SetLayout", "Solutions", new { layoutString = "page1|size15" },null)

我没有测试过,但可能是这个问题..

【讨论】:

  • 我忘了把它放进去。我已经有了第五个参数 = null。我很抱歉。已更正
【解决方案3】:

我自己解决了这个问题。

我不太确定问题出在哪里,但是将 Html.ActionLink() 更改为 Html.RouteLink() 后,我能够定义要使用的 MapRoute

我通过使用以下MapRoute解决了它

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
)

然后我可以像这样使用Html.RouteLink

Html.Routelink("Demos",                       //Display text
               "Default",                     //The MapRoute to use
        new { layoutString = "page1|size15|", //The param (layoutString)
              controller = "Solutions",       //The controller
              action = "SetLayout" })         //The action

我没有对操作进行任何更改:

public ActionResult SetLayout(string layoutString)
{
    Session["Layout"] = layoutString;
    return RedirectToAction("Index", "Solutions");
}

【讨论】:

    猜你喜欢
    • 2017-09-01
    • 2016-11-28
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 2013-08-15
    • 2014-10-23
    • 2017-08-06
    相关资源
    最近更新 更多