使用Html.BeginForm和FormMethod.Get传递另一个查询字符串参数

时间:2017-11-07 14:01:35

标签: c# asp.net-mvc forms razor

背景

我在ASP.NET MVC 5中工作。我有一个产品列表,想要按名称过滤它们。我创建了一个位于产品列表上方的小表单。

CODE

这是Razor表格

@using (Html.BeginForm("Page", "Inventory", routeValues: new { showDeleted = false }, method: FormMethod.Get))
{
  <div class="row">
    <div class="col-md-12">
      <div class="form-group">
        @Html.LabelFor(model => model.Search.SearchTerm, new { @class = "form-label" })
        <div class="controls">
          @Html.EditorFor(m => m.Search.SearchTerm, new { htmlAttributes = new { @class = "form-control" } })
          @Html.ValidationMessageFor(model => model.Search.SearchTerm, "", new { @class = "text-danger" })
        </div>
      </div>
    </div>
    <div class="col-md-12">
      <button type="submit" class="btn btn-primary pull-right filter">Filter Results</button>
    </div>
  </div>
}

以下是它想要的控制器方法:

public ActionResult Page(SearchViewModel search, bool showDeleted, int page = 1)
{
  var viewModel = _productService.GetPagedProducts(search, showDeleted, page);
  return View(viewModel);
}

使用任何搜索条件提交过滤器都会破坏应用程序并出现以下错误:

  

参数字典包含参数&#39; showDeleted&#39;的空条目。非可空类型&#39; System.Boolean&#39; for method&#39; System.Web.Mvc.ActionResult Page(Proj.ViewModels.Shared.SearchViewModel,Boolean,Int32)&#39;在&#39; Proj.Controllers.InventoryController&#39;。可选参数必须是引用类型,可空类型,或者声明为可选参数。

我知道为什么会失败,这是因为showDeleted我的设置被忽略掉了!但我不知道如何解决这个问题。

1 个答案:

答案 0 :(得分:1)

您的代码将使用showDeleted参数的查询字符串生成正确的表单操作网址

action="/Inventory/Page?showDeleted=False"

但由于您使用 GET 作为表单提交方法,因此在提交表单时,浏览器将从表单中读取输入元素值并构建查询字符串并将其附加到表单操作URL 。这将覆盖您在那里的现有查询字符串。

如果要使用GET作为表单方法以查询字符串发送此内容,则表单中的输入元素应具有相同的名称

@using (Html.BeginForm("Page", "Inventory", FormMethod.Get))
{
    @Html.EditorFor(m => m.Search.SearchTerm, 
                          new { htmlAttributes = new { @class = "form-control" } })
    <input type="hidden" name="showDeleted" value="false" />
    <button type="submit" class="btn btn-primary filter">Filter Results</button>

}