I do not get a friendly url in a form with a GET method

I configure this route:

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

When I click the submit button on the form (using the GET method), the URL looks like this:

 http://localhost:00000/Pesquisar?aaa=One&bbb=Two 

But I was expecting:

 http://localhost:00000/Pesquisar/One/Two 
+6
source share
5 answers

When matching a route, it adds it to the end of the list. When a router looks for a rule match, it starts at the very beginning of the list and repeats through it. This will take the first rule that does not correspond to the most specific rule. Since it’s natural to add code to the end, the default rule (which works for almost everything) will be at the beginning.

Try reordering the code this way:

  ///The specific rout which you want to use routes.MapRoute( name: "Pesquisar", url: "{action}/{aaa}/{bbb}/{id}", defaults: new { controller = "Home", action = "Pesquisar", aaa = UrlParameter.Optional, bbb = UrlParameter.Optional, id = UrlParameter.Optional } ); ///The generic catch all router routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); 

More information can be found in this question:
Configure ASP.Net MVC 4 Routing Using Custom Segment Variables

+1
source

When I click the submit button on the form (using the GET method), the URL looks like this:

http://mydomain.com/Pesquisar?aaa=One&bbb=Two

But I was expecting:

http://mydomain.com/One/Two

This is because the browser does not know the desired URL, since the standard method of the Get form is to add the form values ​​to the request queue.

What you most need to do is something like Create canonical URLs, including an identifier and a header pool , except for redirecting to the URL you want if it is not a URL you want to display.

Or you can use jQuery to manually create the URL that you want to submit, but requires more work on the client side.

+1
source

Not sure if you get the clean url directly from the html GET form.

One suggestion would be to POST in action, do what you need to do with the data, and then redirect to your clean URL when complete.

eg.

ViewModel

 public sealed class PesquisarModel { public string aaa { get; set; } public string bbb { get; set; } public string id { get; set; } } 

Actions with the controller :

 [HttpGet] public ActionResult Pesquisar(PesquisarModel m) { return View(); } [HttpPost] [ActionName("Pesquisar")] public ActionResult PesquisarPost(PesquisarModel m) { //do stuff return RedirectPermanent("/pesquisar/" + m.aaa + "/" + m.bbb + "/" + m.id); } 

View

 @model MyApplication.Models.PesquisarModel @using (Html.BeginForm()) { @Html.TextBoxFor(m => m.aaa) @Html.TextBoxFor(m => m.bbb) @Html.TextBoxFor(m => m.id) <button type="submit">Submit</button> } 
0
source

This is the behavior of the browser. When creating a request browser, GET adds all KeyValue pairs to querystring.

The specified route format will be available when we use Html.ActionLink or Html.RouteUrl, etc.

Perhaps you could write some code in OnActionExecuting (or you can use any handler) to restore the RouteData and redirect it with the appropriate URL. Below code is not verified

 var queries = this.Request.QueryString; foreach(var query in queries) { // Add/Update to RequestContext.RouteData } var redirectUrl = Url.RouteUrl("Pesquisar",this.RequestContext.RouteData); Response.Redirect(redirectUrl); 
0
source

Expected Behavior.

The routing system is located on the server side. The browser does not know anything about routes, and what you do happens in the browser.

If you want to get this route, you must compile it on the client side using a special script that uses the <form> action, the values ​​of <input type="text"> .

You cannot generate Url on the server side (which can be done using some of the UrlHelper extension methods), since changes to text fields will not be updated.

This is impractical because if you make changes to the routes, you may forget to update them in your browser scripts, disrupting your application.

You can avoid this problem by creating a server-side URL using the UrlHelper extension method with special placeholders that can be easily replaced on the client side. That is, create a URL like this:

http://localhost/Pesquisar/$aaa$/$bbb$/$id$

providing RouteValues ​​as follows: new {aaa="$aaa$, bbb="$bbb$, id="$id$"} to the UrlHelper method. This url can be stored in the value property of the hidden field.

Then make a browser script for the click event of your button, restore the URL with placeholders from the hidden field, and replace the placeholders with the actual values ​​of the text fields. To complete this run, do the following: document.location = theUrl;

If you want this to be differentnt for many instances, you could create a Helper to bypass the hidden field using Url and javascript, which makes replacements.

The question is, is it worth the effort?

0
source

Source: https://habr.com/ru/post/949172/


All Articles