user2303264
user2303264

Reputation: 115

Routing on GET request with client side

Similar situation to Julian here: MVC - Route with querystring

I can't grasp how to action a form, with GET request, with defined routes and values from form.

(EDIT: essentially same context in terms of problem as Julian's but asking about specific solution(s) in terms of javascript libary and/or custom routing (instead of general areas and explaining why there is an issue and different approach needed to given code); also not using global.asax; over a year since question meaning other options may be available too.)

As a beginner, it is difficult to get far with overwhelming client libraries and having little idea where to start with the relevant custom route provider, which however seems more preferable for simplicity of keeping server side routing and 301 redirect.

Tried different routes (apparently not 'custom') and looked into many libraries but really failing to make any tangible progress.

Any simple pointers e.g. routing example/key words/links, simple client code example (for this context etc.) would be very useful.


Using this tutorial to create a search page for movies, by title and genre.]

Here is my specific code:

RouteConfig:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Movies",
            url: "{controller}/{action}/{title}/{genre}",
            defaults: new 
                {
                    controller = "Home",
                    action = "Index"
                }
        );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new 
                { 
                    controller = "Home",
                    action = "Index",
                    id = UrlParameter.Optional
                }
        );
    }

ActionResult:

public ActionResult SearchIndex(string title, string genre)
{
            var genreQuery = from g in db.Movies
                         orderby g.Genre
                         select g.Genre;
            var genres = new List<string>();
            genres.AddRange(genreQuery.Distinct());
            ViewBag.Genre = new SelectList(genres);

            var movies = from m in db.Movies
                         select m;

            if (!string.IsNullOrEmpty(title))
            {
                movies = movies.Where(s => s.Title.Contains(title));
            }
            if (!string.IsNullOrEmpty(genre))
            {
                movies = movies.Where(s => s.Genre == genre);
            }

            return View(movies);
        }

SearchIndex.cshtml:

    @model IEnumerable<DefaultMvcIA.Models.Movie>

@{
    ViewBag.Title = "SearchIndex";
}

<h2>SearchIndex</h2>

<p>
    @Html.ActionLink("Create New", "Create")
    @using (Html.BeginForm("SearchIndex", "Movies", FormMethod.Get))
    {
        <p>Genre: @Html.DropDownList("Genre", "All")
        Title: @Html.TextBox("Title")<br />
        <input type="submit" value="Filter" /></p>
    }
</p>
<table>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.ReleaseDate)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Genre)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Price)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Title)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.ReleaseDate)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Genre)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Price)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.MovieID }) |
            @Html.ActionLink("Details", "Details", new { id=item.MovieID }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.MovieID })
        </td>
    </tr>
}

</table>

Problem On GET request browser just uses querystring and not set routing in RouteConfig (understandbly). Need to write custom route to redirect these querystrings to route OR use client library. Specific information really useful, as many different routing libraries out there and don't know where to start with (preferable) 301 custom routing method.

Upvotes: 1

Views: 1203

Answers (1)

monkeyhouse
monkeyhouse

Reputation: 2896

EDIT : 8:46 PM

The controller/action, ie. Search/Index can be overloaded to return different results depending on whether there is a querystring and whether it is a get request, etc.

public ActionResult Index(){} will be hit by host/ControllerName/Index

public ActionResult Index(string searchTerm) will be hit by host/ControllerName/Index?searchTerm=ABC

EDIT: 9:23 AM

if you need to change the action to which it posts dynamically, there are javascript libraries that will intercept the get request. If you don't mind using ajax, you can always look into http://www.malsup.com/jquery/form/ to intercept the form request and you can change the link to whatever you want it to be.

EDIT: 6/16 9:22 AM in the code above, there is the line

@using (Html.BeginForm("SearchIndex", "Movies", FormMethod.Get))

This indicates that the Get request will perform a "Get" request to the "SearchIndexController" and the "Movies" ActionResult.

(so it still uses the code in the global.asax routing to route to that controller/action) This routing code in global.asax is always used for every request.


Edits in resoponse to focus on how to access querystrings (to reroute a path)

you can bind to the querystring directly. To avoid duplicating text on other answers, see ASP.NET MVC - Getting QueryString values for some ways to get a value from a querysting.

If you dont want to bind to them directly in the ActionResult method signature, use the Request.Querystring object to access the querystring. ie.

 var searchTerm = Request.QueryString["searchTerm"].ToString();
 var sortColumn = Request.QueryString["sortColumn"].ToString();

or

 var searchTerms = Request.QueryString["searchTerms"].ToString().SplitBy(",")

depending on the syntax of the querystirng...

to redirect a method based on the result of a querystring parameter, you can always return a different action method, or you can redirect to Action

 ie. return this.Index2( ..param...); 

or

 RedirectToAction("ActionName", "ControllerName")

... there are many ways to redirect to an action of your choice.


How to "action" a form isn't really making sense to me.

In mvc, a simple setup is to have a form like

@{using(Html.BeginForm("Index","Home",FormMethod.Post)){
  @Html.LabelFor(m => m.Word)
  @Html.TextBoxFor(m => m.Word, new { @Value = Model.Word})
  <input type="submit" value="Submit">
}

where "Index" is the action name and "Home" is the controller name. This would be routed to the Action method of the HomeController. This routing path can actually be customized in the routing specified in Global.asax. In global.asax, there are code snippets that look like

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

This would route urls of the form A/B/C to AController, ActionResult B with parameter Id=3

I hope this is enough information to help you look for a suitable tutorial to follow. If you are still a student (or still have a college email or have a friend with one), watch videos at http://www.pluralsight.com/training They have great introductory videos that can help you learn mvc3/4 basics.

Upvotes: 1

Related Questions