0

I have a form with a searchbox on it. When someone types something into the search box and hits the search button I am trying ot do a post to capture the search filter and then fire off a view.

Here is the controller code

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

Here is the code from my view up until the part that is tryign to do the submit

<!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> 

If I take the parameter off of the controller function it works fine. If not it seems to crash and try to re display a get which fails because I only have a post function for this. I am guessing I have something screwed up with the parameter but I can't figure out what it is. Any help woudl be greatly appreciated.

UPDATE

Based on feedback I have changed my post to a get

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

and my view code to this

@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> } 

Unfortunately I still have the original issue. If I remove the searchfileter parameter from my controller call then it goes into the call with no problems but when I am expecting the modelbinder to give me a searchfilter it crashes out.

Here is the call I am redirecting to in my search function

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()); } } 

and the view that is displayed

@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> 
8
  • Why would you need a POST? You're not doing any inserts or updates, just fetching results based on a parameter (searchfilter)—use GET. Commented Nov 18, 2016 at 14:55
  • Based on some thing I had seen online since the searchfilter is not there when the page was rendered I needed to do a post to get the value to use. Even if I was able to use a get though this still seems liek an issue with me trying to pass a parameter since the post fires correctly when none are specified Commented Nov 18, 2016 at 15:00
  • As an aside you should not normally return a view from a Post action. Google Post Redirect Get Commented Nov 18, 2016 at 15:07
  • @DaveWade change <button class="btn btn-default" type="submit"><i class="glyphicon glyphicon-search"></i></button> to <input type="submit" class="btn btn-default" <i class="glyphicon glyphicon-search"></i> />.. I believe this has something to do with <button> HTML not working correctly with forms.. Commented Nov 18, 2016 at 15:22
  • I did attempt this but got the same error Commented Nov 18, 2016 at 15:41

5 Answers 5

1

Do a GET instead of a POST—you're not doing any inserts or updates, just fetching results based on a parameter (searchfilter). With a GET, the values of the input elements in your form will be appended as parameters to the query string of the target URL, which would produce something like mywebsite.com/spots/spotsearch?searchfilter=whateverValueInTheInputBox (depending on how you have your routing configured).

Razor:

@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> } 

Controller:

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

Edit: As per @BviLLe_Kid, you can try replacing <button> with <input>.

Edit 2: Can't help but wonder why you are proxying the call to Index via SearchSpots, causing an unnecessary redirect. If all that SearchSpots does is redirect to Index, why not submit the form directly to Index?

Razor:

@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>/> } 

Controller:

// 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()); } } 
Sign up to request clarification or add additional context in comments.

4 Comments

No luck with the get either although I think you are right and I should be doing a GET instead of a POST. After I made the changes and it crashed I removed the parameter from the controller action and it goes in just fine so it seems to have something to do with the parameter I am expecting the modelbinder to provide for me.
why return Index(searchfilter);? If you're returning a view for that particular action, just return View(yourModelHere); and then in your view add @model modelType (if yourModelHere is a string for example, you'd write @model string).
Basically index is the view I want it normally opens up and displays an unfiltered list that you can filter with a text box. I am trying to call this view up which already has a model of the data I am displaying and I just want an initial filter put on the data. I will post the call and view above
you have an extra > after "submit"
0

In agreement with most of the other answers stating that this needs to be an HttpGet request rather than an HttpPost request I believe that this can be solved by changing your 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 } 

Controller:

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

I believe your issue can be related to this. <button> is exactly what it is.. a button.. it basically does nothing, and is mainly used for JS purposes. However, the <input type="submit" /> actually submits the surrounding form.

I hope this helps!

UPDATE

I did need the input to pass the parameter. I still had the same error even after it was being passed and I had to make this final tweak to get it running

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

I needed to redirect instead of trying to return a view

8 Comments

I missed the element type in my answer (shameless copy-pasting), will factor that in.
@trashr0x so you meant to change <button> to <input />?
Nope, I'm saying I've added your suggestion to my answer (though I'm not sure it's the problem).
@trashr0x ahh i see. I haven't heard anything from the OP, so idk.
This solution was the closest to what I needed. The input did get me the parameter passed. I still had the issue and had to change my controller function to do a redirect instead of returning a view. Thanks for the help
|
0

I believe you're missing FormMethod.Post in

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

1 Comment

I did try adding this but with no luck. I still get the same error which seems to be it choking on the parameter I am expecting in the controller function
0

you don't need two forms in your HTML and this code is working and post search text

<!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> 

And you can add [ValidateAntiForgeryToken] in your action

3 Comments

I made these changes but still get the same error as before basically crashes if i am requiring a parameter in my controller action
@DaveWade can you share your get method that display the view ?
I shared the call that Search gets the view from and the view above
0

This is a routing issue. You don't have a route that will hit SearchSpots with a parameter. So either change your route, or change the BeginForm to include the parameter.

ASP.NET MVC - passing parameters to the controller

Pass multiple parameters in Html.BeginForm MVC

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.