MVC BeginForm - 使用GET

时间:2016-05-28 11:33:46

标签: c# asp.net-mvc action

我正在为我的某个应用程序视图实施搜索过滤器。我很难使用@Html.BeginForm()和GET请求将routeValues传递给控制器​​操作。

该操作接受以下属性:

public ActionResult Books(int id, string type, string search)
{
    //rest of the code
}

View的搜索框如下所示:

@model ILookup<string, CityLibrary.Models.Library.Book>
.... 
@using (Html.BeginForm("Books", "Collections", new { id = Model.First().First().CollectionId, type = ViewBag.BookType }, FormMethod.Get, null))
{
    <div class="input-group col-md-4">
        @Html.TextBox("search", null, new { @class = "form-control form-control-fixed-width", @placeholder = "Filter title..." })
        <span class="input-group-btn">
            <button class="btn btn-default" type="submit">
                <span class="glyphicon glyphicon-search"></span>
            </button>
        </span>
    </div>
}

提交搜索框时出现问题。控制器操作获取idsearch字符串,但type始终为null,即使ViewBag.BookType不是null。提琴手说明了这一点:

  

GET / Collections / Books / 2?search = searchterm

这似乎完全忽略了请求中的type参数。

浏览器中的源代码:

<form action="/Collections/Books/2?type=available" method="get">
    <div class="input-group col-md-4">
        <input class="form-control form-control-fixed-width" id="search" name="search" placeholder="Filter title..." type="text" value="" />
        <span class="input-group-btn">
            <button class="btn btn-default" type="submit">
               <span class="glyphicon glyphicon-search"></span>
            </button>
        </span>
    </div>
</form> 

它与GET方法有关吗?我想避免POSTing,因为我必须用基本相同的代码编写另一个控制器动作。

编辑:当我尝试使用GET请求时,似乎会出现问题。 POST表单实际上将所有参数传递给控制器​​操作。那是为什么?

1 个答案:

答案 0 :(得分:1)

此行为符合HTML specifications,特别是对于action的表单,(我的重点)

  

变异操作网址

     

让目标成为新网址,除了其&lt; query&gt;之外,其等于该操作。组件被查询 替换(如果合适,添加U + 003F QUESTION MARK字符(?))。

因此,表单&#39; new { type = ViewBag.BookType }属性中的查询字符串值将替换为由表单控件的名称/值对生成的查询字符串。

解决此问题的两个选项:

  1. BeginForm()方法移除<input type="hidden" name="type" value="@ViewBag.BookType" /> 并为参数添加隐藏输入

    type
  2. 为方法创建自定义路由定义,以便将routes.MapRoute( name: "Books", url: "Collections/Books/{id}/{type}", defaults: new { controller = "Collections", action = "Books" } ); 添加为路由参数,而不是查询字符串值(请注意,这必须在默认路由之前)

    BeginForm()

    以便您当前的<form action="/Collections/Books/2/available" method="get"> 代码生成

    Collections/Books/2/available?search=searchterm
  3. 并且表单提交将生成Intent

    的网址