2011-03-26 135 views
2

我的页面上有一个搜索表单,我想使用GET提交表单。搜索形式如下:MVC路由问题

@using (Html.BeginForm("List", "Search", FormMethod.Get)) 
    { 
     @Html.HiddenFor(model => model.CategoryName) 
     @Html.HiddenFor(model => model.RegionName) 

     <table class="plain"> 
      <tr> 
       <td>From</td> 
       <td>@Html.TextBoxFor(model => model.FromDate)</td> 
      </tr> 
      <tr> 
       <td>To</td> 
       <td>@Html.TextBoxFor(model => model.ToDate)</td> 
      </tr> 
      <tr> 
       <td colspan="2"><input type="submit" id="Search" value="Search" /> 
       </td> 
      </tr> 

     </table> 
    } 

有这样的视图模型:

public class SideNavModel 
{ 
    public string CategoryName { get; set; } 
    public string RegionName { get; set; } 
    public string FromDate { get; set; } 
    public string ToDate { get; set; } 
} 

我的路线设置这样的:

routes.MapRoute(
     "Search2", 
     "Search/{CategoryName}/{RegionName}/{FromDate}/{ToDate}", 
     new { controller = "Search", action = "List", CategoryName = "All", RegionName = "All", FromDate = "", ToDate = "" }); 

    routes.MapRoute(
     "Search1", 
     "Search/{CategoryName}/{RegionName}", 
     new { controller = "Search", action = "List", CategoryName = "All", RegionName = "All" }); 

所以,当我实际上做的搜索,URL发送到:

/Search?CategoryName=All&RegionName=SomeRegion&FromDate=20110301&ToDate=20110317 

,我真正想要的:

/Search/All/SomeRegion/20110301/20110317 

我不知道这是否是显著但这种设置方式,搜索需要出现在每一页上。所以,在_layout.cshtml“母版”,我有这样的:

@{Html.RenderAction("LoadNavigationSide");} 

,并在BaseController,这样的:

public PartialViewResult LoadNavigationSide(SideNavModel model) 
{ 
    // other code 
    // ... 
    return PartialView("NavigationSide", model); 
} 

(它需要这样,因为它多一点只是返回模型 - 所以它不能是一个简单的@ Html.Partial(“NavigationSide”)调用)

回答

3

如果您在表单上使用method="GET",HTML规范指出用户代理应该向action属性中使用的url发送GET请求,并将值附加为查询字符串参数。

如果您在表单上使用method="POST",HTML规范指出用户代理应该向action属性发送POST请求,并在POST请求正文中写入表单字段的值。

结论:你试图实现的东西对纯HTML来说是不可能的。

实现此目的的一种方法是使用javascript并订阅表单的onsubmit事件,构建请求url并在取消默认行为后手动重定向到它。 jQuery示例:

$('form').submit(function() { 
    var url = this.action + '/' + $('#FromDate').val() + '/' + $('#ToDate').val(); 
    window.location.href = url; 
    return false; 
}); 

但是我个人会坚持使用POST动词。

+0

感谢Darin。我很惊讶,他的框架不支持,但我已经与你提供的JavaScript方法一起工作。作为一个便笺,我想使用GET,因为如果我要从某个页面进行搜索,可以说'/ Search/All/Region/20110101/20110201',然后再次从该页面进行搜索,POST请求会仍然有旧的URL - 它不会反映新的日期 – Beno 2011-03-26 12:44:20

+0

@quagland,这不是ASP.NET MVC框架的限制。 HTML规范是如何定义的,浏览器只是遵循这个规范。 – 2011-03-26 12:49:03

+0

没错,现在我有更多的想法了。谢谢你的帮助 – Beno 2011-03-26 12:55:27

0

您的解决方案中是否有SearchController?这听起来像您可能会路由到默认路由,如果您在自定义搜索路由之前声明了默认路由,这是有道理的。

另外,Haack's Route Debugger是测试路由的好工具。

+0

是的,我有一个SearchController。 SearchController正在接收参数OK。 – Beno 2011-03-26 01:45:22

+0

我看了一下Route调试器(非常方便)。如果我有像:/ Search/All/SomeRegion这样的网址 - 我希望这可以通过earch/{CategoryName}/{RegionName}路由。目前,它正在通过搜索/ {CategoryName}/{RegionName}/{FromDate}/{ToDate}进行提取。有没有办法做到这一点? – Beno 2011-03-26 02:07:04

+1

尝试删除指定默认参数的部分。看起来这是他们唯一可以匹配的原因 – smartcaveman 2011-03-26 02:14:39