MVC奇怪的路由行为

时间:2016-05-27 09:31:05

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

我在MVC中遇到了一些奇怪的问题。这是我的情景:

  1. 访问网站后,用户会看到首页:testproject.com:57416/Home
  2. 用户左侧有一个菜单,菜单项为“Solutions”。
  3. 用户按下菜单项“解决方案”,菜单项展开,显示5个子项目。
  4. 用户按子项“演示”,然后重定向到testproject.com:57416/Solutions/SetLayout?layoutString=page1%7Csize15
  5. 当定义了参数layoutString时,网格( DevExpress )知道如何过滤要显示的数据。
  6. 网格呈现给用户,他现在可以在网格中导航,操纵布局。
  7. 用户现在想要再次看到干净的演示布局,并且按下菜单项“解决方案” - >子项“演示”。
  8. 在这种情况下,操作ActionResult SetLayout(string layoutString)未被点击,而是点击操作ActionResult Index(),因此未设置布局,因为layoutString未作为参数发送
  9. 用户重定向到的网址如下所示:testproejct.com:57416/Solutions?undefined=undefined
  10. 这可能有点令人讨厌,但这是我解释我的场景的最佳方式,因为我之前从未见过这样的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 }
    );
    

3 个答案:

答案 0 :(得分:0)

看起来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键。

答案 1 :(得分:0)

在actionlink中将第5个参数传递为null,如下所示:

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

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

答案 2 :(得分:0)

我设法自己解决了这个问题。

我不太确定问题是什么,但是将Html.ActionLink()更改为Html.RouteLink()我能够定义要使用的MapRoute。< / p>

我使用以下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");
}