Html.BeginForm如何在提交时传递路由id参数和get参数?

5

我在我的MVC项目中有一个像这样的方法:

[Route("Categories/{categoryId}")]
public ActionResult List(SearchQueryCommand searchQuery) {
    //Stuff
    return View();

}

这个方法的调用方式是:'www.myweb.com/Categories/212'

但我有一个下拉列表和一个表单,可以对此查询进行排序,并将其发送回服务器以获取排序后的结果。 我在我的Razor视图中有以下代码:

@using (Html.BeginForm(new { categoryId = Model.CategoryId }))
{
                <div>
                    <small>@Html.LabelFor(m => m.Order, "sort by")</small>
                    @Html.DropDownListFor(m => m.Order, Model.ProductSortByOptions, new { onchange = "this.form.submit();" })
                    <button class="nojs" type="submit">ok</button>
                </div>
}

我的问题是我不知道如何格式化我的代码,使得我的网址看起来像这样:'www.myweb.com/Categories/213?Order=MinPrice'

我有哪些选项可以实现这个目标?

4个回答

2
你的表单方法需要为GET
@using (Html.BeginForm(new { categoryId = Model.CategoryId }, FormMethod.Get))

这样,当表单提交时,所有的表单字段都将被添加到URL的查询字符串中。

要发布到特定的操作方法,您需要在BeginForm定义中指定它们。我不太熟悉基于属性的路由定义,但其中一个应该可以工作:

@using (Html.BeginForm("List", "Categories", new { categoryId = Model.CategoryId }, FormMethod.Get))

或者

@using (Html.BeginForm("Index", "Categories", new { categoryId = Model.CategoryId }, FormMethod.Get))

第一个提到的方法重载BeginForm(object routeValues,FormMethod method)不存在。 - Jack Miller

1

我使用RedirectToRoute在beginform POST方法中路由参数,这会生成一个302 http响应,但我不知道其他的方法。

在routeconfig中

routes.MapRoute(
           name: "list",
           url: "{bti}-e-{bop}-e-{blo}-e-{bzo}-e-{bpr}-e-{bha}-e-{bor}",
           defaults: new { controller = "home", action = "list", bpr = UrlParameter.Optional, bha = UrlParameter.Optional, bor = UrlParameter.Optional }
           );

动作获取:
public ActionResult li(int activepage = 0,  Buscador bu = null)
    {
    your code...
    return View(model);
    }

动作提交:
[HttpPost]
    public ActionResult li(int activepage = 0,Buscador bu = null)
    {
     ..my code to format values...
     ..send values below that interest me routing.. 
     return RedirectToRoute("list", new System.Web.Routing.RouteValueDictionary { { "bti", bu.bti }, { "bop", bu.bop }, { "blo", bu.blo }, { "bzo", bu.bzo }, { "bpr", bu.bpr }, { "bha", bu.bha }, { "bor", bu.bor } });
    }

这项工作对我来说没问题。
我的英语非常糟糕,很抱歉。

1
我已经找到了解决方案!而且不是使用Html.BeginForm
我的代码如下:
<form action="@Url.Action()" method="get">
     <div>
        <small>@Html.LabelFor(m => m.Order, "ordenar por")</small>
        @Html.DropDownListFor(m => m.Order, Model.ProductSortByOptions, new { onchange = "this.form.submit();" })
        <button class="nojs" type="submit">ok</button>
     </div>
</form> 

这将始终将我的表单操作设置为:{类别}/{类别ID},因为它是一个GET,所以Order将作为查询参数设置,就像我想要的那样。

只是为了澄清,这可以使用 Html.BeginForm 完成,你只需要在到达表单方法之前填写所有参数,例如:Html.BeginForm("List", "YourController", new { categoryId = Model.CategoryId }, FormMethod.Get)。尽管如此,在这种情况下,我通常会采取与你相同的路径,因为它稍微简单一些,虽然你不需要 Url.Action() 部分:action="" 同样有效。 - Chris Pratt
它不是以那种方式工作的...因为它生成的URL类似于:'www.myweb.com/YourController/List?categoryId=123',而且这个URL无法与我的方法上的路由配置一起使用:[Route("List/{categoryId")] - Phoenix_uy
如果您正在使用属性路由,则应该在RouteConfig.cs中注释或删除默认路由。然后,它就可以工作了。 - Chris Pratt

1
你需要在表单标签中添加 GET 方法。
@using (Html.BeginForm("MethodName", "YourController",FormMethod.Get))

然后您的表单标签将生成GET请求,表单中的所有参数都将出现在URL查询字符串中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接