2013-07-11 13 views
6

ho messa a punto di un percorso del genere:Non ricevo url amichevole in un modulo con metodo GET

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

Quando si preme il pulsante Invia in una forma (con metodo GET) l'url è così:

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

Ma mi aspettavo per:

http://localhost:00000/Pesquisar/One/Two 
+1

si verifica la stessa cosa quando l'ID ha un valore? –

+0

@JeroenVannevel: sì. Se digito manualmente nel browser funziona ('http: // localhost: 00000/Pesquisar/foo/bar/1') ma tramite il modulo GET non lo fa. Voglio dire, funziona, ma non con un URL amichevole. – Fabricio

risposta

0

Non sono sicuro se si ottiene un URL pulita direttamente da un form html GET.

Un suggerimento sarebbe quello di POST a un'azione, fare ciò che è necessario fare con i dati, quindi al termine, reindirizzare al tuo URL pulito.

ad es.

ViewModel:

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

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

Vista:

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

Quando si mappa un r fuori, lo aggiunge alla fine di una lista. Quando il router cerca la corrispondenza della regola, inizia all'inizio della lista e la attraversa. Prenderà la prima regola che corrisponde, non la regola più specifica. Perché è naturale aggiungere il codice alla fine, la regola predefinita (che funziona per quasi tutto) sarà all'inizio.

Prova a ri-ordinare il vostro codice per assomigliare a questo:

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

Maggiori informazioni possono essere trovate in questa domanda:
Setting up ASP.Net MVC 4 Routing with custom segment variables

1

Quando si preme il pulsante Invia in una forma (con metodo GET) l'url è così:

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

Ma mi aspettavo per:

http://mydomain.com/One/Two

Questo perché il del browser ignora l'url di fantasia che si desidera, come la forma standard Get metodo è quello di forma di accodamento valori nella querystring.

Quello che probabilmente devi fare è qualcosa come Creating Canonical URLs including an id and title slug, eccetto il reindirizzamento all'URL che vuoi se non è l'url che vuoi visualizzare.

Oppure è possibile utilizzare jQuery per creare manualmente l'URL che si desidera inviare, ma richiede più lavoro sul lato client.

0

Questo è il comportamento del browser. Quando si effettua un browser di richiesta GET, tutte le coppie KeyValue vengono aggiunte a querystring.

Il formato percorso citato sarà disponibile, quando usiamo Html.ActionLink o Html.RouteUrl ecc

Probabilmente si potrebbe scrivere qualche codice OnActionExecuting (o è possibile utilizzare qualsiasi gestore) per ricostruire RouteData e reindirizzare con url appropriato. Sotto il codice non è testato

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

Questo è un comportamento previsto.

Il sistema di routing si trova sul lato server. Il browser non sa nulla delle rotte e ciò che stai facendo accade nel browser.

Se si desidera ottenere tale percorso, è necessario comporlo sul lato client con uno script personalizzato che utilizza l'azione <form>, i valori dei valori <input type="text">.

Non è possibile generare l'Url sul lato server (operazione che potrebbe essere eseguita con alcuni metodi di estensione UrlHelper) poiché le modifiche alle caselle di testo non verrebbero aggiornate.

Questo non è consigliabile perché se si apportano modifiche ai percorsi, è possibile dimenticare di aggiornarli negli script del browser, rompendo l'applicazione.

È possibile evitare questo problema creando l'URL sul lato server utilizzando un metodo di estensione UrlHelper con segnaposti speciali, che potrebbero essere facilmente sostituiti sul lato client. Cioè generare un URL simile a questo:

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

fornendo RouteValues ​​come questo: new {aaa="$aaa$, bbb="$bbb$, id="$id$"} ad un metodo UrlHelper. Questo URL può essere memorizzato nella proprietà value di un campo nascosto.

Quindi, creare uno script del browser per l'evento click del pulsante, recuperare l'url con i segnaposto dal campo nascosto e sostituire i segnaposto con i valori effettivi delle caselle di testo. Per eseguire il comando get: document.location = theUrl;

Se si desidera d questo per molte istanze diverse, è possibile creare un Helper per geenrare il campo nascosto con l'Url e un javascript che effettua le sostituzioni.

La domanda è ... vale la pena?

Problemi correlati