2011-03-26 211 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