MVC BeginForm - 使用 GET 将参数传递给控制器
MVC BeginForm - passing parameters to controller using GET
我正在对我的应用程序的一个视图实施搜索过滤器。我努力使用 @Html.BeginForm()
和 GET 请求将 routeValues 传递给控制器操作。
该操作接受以下属性:
public ActionResult Books(int id, string type, string search)
{
//rest of the code
}
视图的搜索框如下所示:
@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>
}
提交搜索框时出现问题。控制器操作获取 id
和 search
字符串,但 type
始终是 null
,即使 ViewBag.BookType
不是 null
。 Fiddler 显示:
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方法有关系吗?我想避免发布,因为我必须使用基本相同的代码编写另一个控制器操作。
编辑: 似乎问题发生在我尝试使用 GET 请求时。发布表单实际上将所有参数传递给控制器操作。这是为什么?
此行为符合 HTML specifications,特别是对于带有 method="get"
的表格,(我强调)
Mutate action URL
Let destination be a new URL that is equal to the action except that its <query> component is replaced by query (adding a U+003F QUESTION MARK character (?) if appropriate).
因此,表单 action
属性中的查询字符串值将替换为 name/value 对表单控件生成的查询字符串。
解决此问题的两个选项:
从BeginForm()
方法中移除new { type = ViewBag.BookType }
并为参数
添加隐藏输入
<input type="hidden" name="type" value="@ViewBag.BookType" />
为该方法创建自定义路由定义,以便将 type
添加为路由参数,而不是查询字符串值(注意这必须在默认路由之前)
routes.MapRoute(
name: "Books",
url: "Collections/Books/{id}/{type}",
defaults: new { controller = "Collections", action = "Books" }
);
这样您当前的 BeginForm()
代码将生成
<form action="/Collections/Books/2/available" method="get">
并且表单提交将导致 url 的 Collections/Books/2/available?search=searchterm
我正在对我的应用程序的一个视图实施搜索过滤器。我努力使用 @Html.BeginForm()
和 GET 请求将 routeValues 传递给控制器操作。
该操作接受以下属性:
public ActionResult Books(int id, string type, string search)
{
//rest of the code
}
视图的搜索框如下所示:
@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>
}
提交搜索框时出现问题。控制器操作获取 id
和 search
字符串,但 type
始终是 null
,即使 ViewBag.BookType
不是 null
。 Fiddler 显示:
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方法有关系吗?我想避免发布,因为我必须使用基本相同的代码编写另一个控制器操作。
编辑: 似乎问题发生在我尝试使用 GET 请求时。发布表单实际上将所有参数传递给控制器操作。这是为什么?
此行为符合 HTML specifications,特别是对于带有 method="get"
的表格,(我强调)
Mutate action URL
Let destination be a new URL that is equal to the action except that its <query> component is replaced by query (adding a U+003F QUESTION MARK character (?) if appropriate).
因此,表单 action
属性中的查询字符串值将替换为 name/value 对表单控件生成的查询字符串。
解决此问题的两个选项:
从
添加隐藏输入BeginForm()
方法中移除new { type = ViewBag.BookType }
并为参数<input type="hidden" name="type" value="@ViewBag.BookType" />
为该方法创建自定义路由定义,以便将
type
添加为路由参数,而不是查询字符串值(注意这必须在默认路由之前)routes.MapRoute( name: "Books", url: "Collections/Books/{id}/{type}", defaults: new { controller = "Collections", action = "Books" } );
这样您当前的
BeginForm()
代码将生成<form action="/Collections/Books/2/available" method="get">
并且表单提交将导致 url 的 Collections/Books/2/available?search=searchterm