ASP.NET MVC BeginForm无法使用参数发布

时间:2016-11-18 14:50:04

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

我有一个带有搜索框的表单。当有人在搜索框中输入内容并点击搜索按钮时,我正在尝试使用帖子捕获搜索过滤器,然后触发视图。

这是控制器代码

public class SpotsController : Controller
{
    [HttpPost]
    [AllowAnonymous]
    public ActionResult SearchSpots(string searchfilter)
    {
        //your code here....
        return Index(searchfilter);
    }

以下是我查看的代码,直到尝试执行提交的部分

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - Haunt Spotter</title>
</head>
<form id="__AjaxAntiForgeryForm" action="#" method="post"><@Html.AntiForgeryToken()></form>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
        </div>
        <div class="navbar-collapse collapse">
            @using (Html.BeginForm("SearchSpots", "Spots"))
            {
                <input id="searchfilter" type="text" class="form-control" autocomplete="off" placeholder="Search" name="searchfilter">
                <button class="btn btn-default" type="submit"><i class="glyphicon glyphicon-search"></i></button>
            }
        </div>
    </div>
</div>

如果我从控制器功能中取出参数,它可以正常工作。如果不是它似乎崩溃并尝试重新显示失败的get,因为我只有一个post功能。我猜我有一些搞砸了参数的东西,但我无法弄清楚它是什么。任何帮助都会受到高度赞赏。

更新

根据反馈,我已将帖子更改为获取

    [HttpGet]
    [AllowAnonymous]
    public ActionResult SearchSpots(string searchfilter)
    {
        //your code here....
        return Index(searchfilter);
    }

和我的观看代码

@using (Html.BeginForm("SearchSpots", "Spots", FormMethod.Get, null))
{
    <input id="searchfilter" type="text" class="form-control" autocomplete="off" placeholder="Search" name="searchfilter">
    <button class="btn btn-default" type="submit"><i class="glyphicon glyphicon-search"></i></button>
}

不幸的是我仍然有原始问题。如果我从我的控制器调用中删除了searchfileter参数,那么它会进入调用而没有任何问题,但是当我希望模型绑定器给我一个搜索过滤器时它会崩溃。

以下是我在搜索功能中重定向的电话

private ApplicationDbContext db = new ApplicationDbContext();

    // GET: Spots
    public ActionResult Index(string filter = "")
    {
        ViewBag.initialFilter = filter;
        if (User.IsInRole("SiteAdmin"))
        {
            return View(db.Spots.ToList());
        }
        else
        {
            return View(db.Spots.Where(x => x.Approved).ToList());
        }

    }

和显示的视图

@model IEnumerable<HauntSpots.Models.Spot>

@{
    ViewBag.Title = "Index";
}

<h2 class="align-right">Haunt Spots</h2>

@if (Context.User.IsInRole("SiteAdmin"))
{ 
    <p style="padding-top:20px">

    <a href="@Url.Action("Create")" title="Add New Spot" class="btn btn-primary"><i class="icon-plus-sign"></i> Add New</a>
    </p>
}

<table id="dt-spots" class="table table-striped">
    <thead>
        <tr>
        <th></th>
        <th></th>
        <th></th>
        @if (Context.User.IsInRole("SiteAdmin"))
        {
            <th></th>
        }
    </tr>
</thead>
<tbody>

    @foreach (var item in Model)
{

        <tr>
            <td>
                @if (Context.User.IsInRole("SiteAdmin"))
                {
                    @Html.Hidden(Url.Action("Edit", "Spots", new { id = item.Id }))
                    <a style="color: Red; vertical-align: middle; font-size: 2em" href="@Url.Action("Delete", "Spots", new { id = item.Id })" title="Delete Spot" class="btn"><i class="icon-remove-sign"></i></a>
                }
                else
                {
                    @Html.Hidden(Url.Action("Details", "Spots", new { id = item.Id }))
                }
            </td>
            <td>

                @if (item.Image == null)
                {
                    <img width="100" height="100"
                         src="~/Content/Images/NoPhoto.jpg" class="img-rounded" />
                }
                else
                {
                    <img width="100" height="100"
                         src="@item.Image" class="img-rounded"/>
                }
            </td>
            <td >
                <div class="form-group pull-left col-md-2">
                    <h4>@item.Title </h4>
                    <h5 style="clear: left">
                        @if (item.Address != null)
                        {
                            <span>@item.Address</span>
                            <br/>
                        }

                        @if (item.State == null)
                        {
                            <span>@item.City</span><br/>
                            <span>@item.Country</span>
                        }
                        else
                        {
                            if (item.State == "")
                            {
                                <span>@item.City</span>
                                <br/>
                                <span>@item.Country</span>
                            }
                            else
                            {
                                <span>@item.City, @item.State</span>
                                <br/>
                                <span>@item.Country</span>
                            }
                        }
                    </h5>
                </div>
                <div class="form-group pull-left col-md-8">
                    <h6>@item.Summary</h6>
                </div>
            </td>
            @if (Context.User.IsInRole("SiteAdmin"))
            {
                <td>
                    @if (@item.Approved)
                    {
                        <span style="color: green">Approved</span>
                }
                else
                {
                        <span style="color: red">Not Approved</span>
                }
                </td>
            }
        </tr>
    }
    </tbody>
</table>

<script type="text/javascript">
    $(document).ready(function () {
        //Initalize and configure DataTables
        $('#dt-spots').dataTable({
            "oSearch": { "sSearch": "@ViewBag.initialFilter" }
        });


        $("tbody").on("click", "tr", function () {
            window.location = $(this).find('input').attr('name');
        });
    });
</script>

5 个答案:

答案 0 :(得分:1)

执行GET而不是POST - 您没有进行任何插入或更新,只是根据参数(searchfilter)获取结果。使用GET时,表单中输入元素的值将作为参数附加到目标网址的查询字符串中,这会产生类似mywebsite.com/spots/spotsearch?searchfilter=whateverValueInTheInputBox的内容(具体取决于您配置路由的方式) )。

剃刀:

@using (Html.BeginForm("SearchSpots", "Spots", FormMethod.Get, null))
{
    <input id="searchfilter" type="text" class="form-control" autocomplete="off" placeholder="Search" name="searchfilter">
    <button class="btn btn-default" type="submit"><i class="glyphicon glyphicon-search"></i></button>       
}

控制器:

public class SpotsController : Controller
{
    [HttpGet]
    [AllowAnonymous]
    public ActionResult SearchSpots(string searchfilter)
    {
        // ...        
    }
}

修改:根据@BviLLe_Kid,您可以尝试将<button>替换为<input>

编辑2:不禁想知道为什么您通过Index代理对SearchSpots的调用,导致不必要的重定向。如果SearchSpots所做的一切都重定向到Index,为什么不直接将表单提交给Index

剃刀:

@using (Html.BeginForm("Index", "Spots", FormMethod.Get, null))
{
    <!-- remember to rename to name="filter" below -->
    <input id="filter" type="text" class="form-control" autocomplete="off" placeholder="Search" name="filter">
    <input class="btn btn-default" type="submit" <i class="glyphicon glyphicon-search"</i>/>
}

控制器:

// GET: Spots
public ActionResult Index(string filter = "")
{
    ViewBag.initialFilter = filter;
    if (User.IsInRole("SiteAdmin"))
    {
        return View(db.Spots.ToList());
    }
    else
    {
        return View(db.Spots.Where(x => x.Approved).ToList());
    }

}

答案 1 :(得分:0)

我相信你

中缺少FormMethod.Post

@using (Html.BeginForm("SearchSpots", "Spots", FormMethod.Post)) {...

答案 2 :(得分:0)

您的HTML中不需要两个表单,此代码正在运行并发布搜索文本

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - Haunt Spotter</title>
</head>
  <body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
            </div>
            <div class="navbar-collapse collapse">
                @using (Html.BeginForm("SearchSpots", "Spots", FormMethod.Post))
                {
                    @Html.AntiForgeryToken()
                    <input id="searchfilter" type="text" class="form-control" autocomplete="off" placeholder="Search" name="searchfilter">
                    <button class="btn btn-default" type="submit"><i class="glyphicon glyphicon-search"></i></button>
                }
            </div>
        </div>
    </div>

您可以在行动中添加[ValidateAntiForgeryToken]

答案 3 :(得分:0)

与大多数其他答案一致,表明这需要是HttpGet请求而不是HttpPost请求,我相信可以通过更改HTML来解决此问题。

HTML:

@using (Html.BeginForm("SearchSpots", "Spots", FormMethod.Get, null))
{
    <input id="searchfilter" type="text" class="form-control" autocomplete="off" placeholder="Search" name="searchfilter">
    <input class="btn btn-default" type="submit" <i class="glyphicon glyphicon-search"</i>/>       // part that needs changing
}

控制器:

[HttpGet]
public ActionResult SearchSpots(string searchfilter)
{
    // logic       
}

我认为您的问题可能与this有关。 <button>正是它的一个按钮..它基本上什么都不做,主要用于JS目的。但是,<input type="submit" />实际提交周围的表单。

我希望这有帮助!

更新

我确实需要输入来传递参数。即使它被传递后我仍然有同样的错误,我不得不进行最后的调整以使其运行

[HttpGet]
    [AllowAnonymous]
    public ActionResult SearchSpots(string searchfilter)
    {
        return RedirectToAction("Index", new { filter = searchfilter}); 
    }

我需要重定向而不是尝试返回视图

答案 4 :(得分:0)

这是路由问题。您没有使用参数命中SearchSpots的路线。因此,要么更改路线,要么更改BeginForm以包含参数。

ASP.NET MVC - passing parameters to the controller

Pass multiple parameters in Html.BeginForm MVC