1

I'm new to MVC and am designing a simple part search tool. I want the URL to update with the search terms in the controller/action/id format, like:

http://localhost/Materials/Search/PartA

However, it updates like this:

http://localhost/Materials/Search?id=PartA

When I enter the desired URL, it works. However, searching for a new part from the same window causes issues:

http://localhost/Materials/Search/PartA?id=PartB

What am I doing wrong? I thought about a redirect using javascript, but then I'd also have to check the URL string to see if the ID is already embedded in the URL. I'm sure others have dealt with this issue so just wanted to know what the best practice for this is.

Controller:

Namespace MyApp.Controllers
  Public Class MaterialsController
    Inherits System.Web.Mvc.Controller

    '
    ' GET: /Materials

    Function Index() As ActionResult
        Return View()

    End Function

    Function Search(Optional ByVal id As String = "") As ActionResult
        If String.IsNullOrWhiteSpace(id) Then
            id = "Enter a part number to search."
        Else
            id = "Part search for " + id + "."
        End If
        Return View("~/Views/Materials/Search.vbhtml", Nothing, id)
    End Function

 End Class
End Namespace

View:

    @ModelType string

    @Code
        ViewData("Title") = "Search"
    End Code

    <h2>Search</h2>


    @Code
        Using (Html.BeginForm("Search", "Materials", FormMethod.Get))
        @<p>@Html.TextBox("id", Nothing, New With {.maxlength = 20, .style = "width:200px"})
           <input type="submit" value="Search" />
        </p>
        End Using
    End Code

    <h3>@Model</h3>
fotijr
  • 946
  • 11
  • 20

3 Answers3

1

If you want the id from the text box to be in the URL you will need to make a request with the id in the URL instead of posting the value in a form. You will need to use some javascript to construct the URL and get the value from the text box. I prefer to use jQuery. You can get rid of the form and change the submit button to a regular button and do something like this:

HTML

@Html.TextBox("id", Nothing, New With {.maxlength = 20, .style = "width:200px"})
<input type="button" id="search" value="Search" />

Javascript

// this is jQuery's short hand and analogue to document.ready
$(function () {

    // attach a click handler to the Search button
    $('#search').click(function () {

        // make a request to /Materials/Search with the id of the text box
        $(location).attr('href', '/Materials/Search/' + $('#id').val());

    }):

});
asymptoticFault
  • 4,491
  • 2
  • 19
  • 24
  • Thanks, this did the trick! I modified it slightly to work with older versions of IE, which is an unfortunate requirement for this project. – fotijr Aug 19 '13 at 13:26
  • You're welcome, glad it worked out :) I think jQuery 1.x works all the way back to IE 6. – asymptoticFault Aug 19 '13 at 13:32
  • It does, but you need to add the function using onclick in HTML instead of .click. That's what I discovered reading [this](http://stackoverflow.com/questions/6348494/addeventlistener-vs-onclick) when implementing your solution. – fotijr Aug 19 '13 at 13:36
  • Ah ok, fair enough. Either way, glad you were able to achieve the desired functionality. – asymptoticFault Aug 19 '13 at 13:50
0

Check the route mapping class (RouteConfig) to sort out the url structure.

This said using GET actions on a Form has a lot of cons if you don't know what the querystring will be : http://www.w3schools.com/tags/att_form_method.asp.

Try changing the form action to be a POST and then from the Search method you can then execute a RedirectToAction to a Result ActionMethod (accepting GET this time) passing as GET parameters the values you did get from your post. This way you can using a ViewModel in the POST, the FORM will be secure and generally you'll have more control over the urls.

Giorgio Minardi
  • 2,765
  • 1
  • 15
  • 11
  • The RouteConfig was working as intended, I had verified this using Route Debugger. I followed asymptoticFault's suggestion and just did the URL redirect using javascript. – fotijr Aug 19 '13 at 13:33
0

After implementing asymptoticFault's suggestion, here is my modified view. I changed the method for adding a javascript event to be compatible with versions older than IE9. I also removed the form tag, and added a javascript method to call the redirect function when the enter key is pressed.

    @ModelType string

    @Code
       ViewData("Title") = "Search"
    End Code

    <h2>Search</h2>


    <p>
        <input id="searchString" type="text" onkeypress="checkForEnter()" style ="width:200px" maxlength="20">
        <input type="button" id="search" value="Search" onclick="searchPart()" />
    </p>

    <h3>@Model</h3>


<script type="text/javascript">
   function searchPart() {

        // make a request to /Materials/Search with the id of the text box
       $(location).attr('href', '/Materials/Search/' + $('#searchString').val());
   };

   function checkForEnter() {
       $("#searchString").keyup(function (event) {
           if (event.keyCode == 13) {
               $("#search").click();
           }
       });
   };

</script>
fotijr
  • 946
  • 11
  • 20