2011-08-16 11 views
6

Ho un'applicazione ASP.NET MVC 3 che registra le voci del pedometro di un utente. Un utente può visualizzare tutte le voci più recenti del pedometro visitando /Pedometer e può filtrare per anno, anno/mese o anno/mese/data visitando URL come /Pedometer/2011, /Pedometer/2011/08 e /Pedometer/2011/08/15, rispettivamente.Perché questo parametro del percorso è virato sulla querystring?

Ho creato due percorsi mappati in Global.asax. Il primo percorso, mostrato di seguito, è ciò che consente i vari pattern URL per il filtraggio per data. La seconda route (non mostrata) è la route MVC ASP.NET predefinita.

routes.MapRoute(
    "PedometerEntries", // Route name 
    "Pedometer/{year}/{month}/{day}", // URL with parameters 
    new 
    { 
     controller = "Pedometer", 
     action = "Index", 
     year = UrlParameter.Optional, 
     month = UrlParameter.Optional, 
     day = UrlParameter.Optional 
    }, // Parameter defaults 
    new 
    { 
     year = @"\d{4}", 
     month = @"([012]?\d{1})?", 
     day = @"(([1-9])|([12][0-9])|(3[0-1]))?" 
    } // Parameter constraints 
); 

Ecco la mia domanda. Ho una vista in cui voglio creare un collegamento del modulo: currentUrl?format=csv, che consentirà all'utente di scaricare le voci del pedometro per l'URL richiesto in un formato CSV. Quindi, se un utente sta visitando /Pedometer, il collegamento per il download sarà /Pedometer?format=csv. Se l'utente sta visitando /Pedometer/2011/08, il collegamento per il download sarà /Pedometer/2011/08?format=csv.

per creare un link che ho aggiunto un HTML personalizzato Helper nominato DownloadToExcel con il seguente codice:

public static MvcHtmlString DownloadToExcel(this HtmlHelper helper, string linkText) 
{ 
    RouteValueDictionary routeValues = helper.ViewContext.RouteData.Values; 

    // Add the format parameter to the route data collection, if needed 
    if (!routeValues.ContainsKey("format")) 
     routeValues.Add("format", "csv"); 

    return helper.ActionLink(linkText,       // Link text 
           routeValues["action"].ToString(), // Action 
           routeValues);      // Route values 
} 

Quando aggiungo il @Html.DownloadToExcel() marcatura a mio avviso, si genera un link, ma qui sta il problema - quando l'utente visita le voci recenti o le voci filtrate per anno/mese o anno/mese/data, funziona come previsto, ma non quando l'utente visita l'URL del filtro dell'anno.

L'elenco che segue mostra l'URL l'utente visita e l'URL corrispondente generato dal Html Helper personalizzato:

  • Visiting: /Pedometer - Download link: /Pedometer?format=csv
  • Visiting: /Pedometer/2011 - Download link: /Pedometer?year=2011&format=csv
  • Visiting: /Pedometer/2011/08 - download link: /Pedometer/2011/08?format=csv
  • Visiting: /Pedometer/2011/08/15 - download link: 0.123.852,86009 milioni

Perché è quando si visita /Pedometer/2011 il link di download è /Pedometer?year=2011&format=csv e non /Pedometer/2011?format=csv? E perché non funziona per quel caso, ma funziona come previsto per i casi anno/mese e anno/mese/data?

Grazie

risposta

6

Questo problema è molto probabilmente causato da this bug descritto da Phil Haack sul suo blog. C'è un bug di regressione introdotto in ASP.NET MVC 3 quando si hanno due parametri URL facoltativi consecutivi.

+0

Questo lo spiega, grazie per il testa a testa. :-) –

4

ho creato una piccola applicazione MVC 3 con il codice che hai fornito e ottenuto esattamente lo stesso comportamento come descritto.

Se vado a http://localhost:51181/pedometer/2011 il collegamento generato sarebbe http://localhost:51181/Pedometer?year=2011&format=csv.

Ma se inserissi esplicitamente il nome dell'azione (Indice), il rendering sarebbe corretto.

Visitando http://localhost:51181/pedometer/index/2011 genererà il seguente link:

http://localhost:51181/pedometer/index/2011?format=csv

Sembra che il percorso corretto non è sempre utilizzato dal metodo di estensione HtmlHelper.

Se aggiungo il seguente percorso appena sotto il percorso personalizzato, ma prima del percorso MVC predefinito funziona OK.

routes.MapRoute(
    "PedometerDefault", 
    "Pedometer/{year}", 
    new { controller = "Pedometer", action = "Index", 
      year = UrlParameter.Optional } 
); 
+0

Questo sembra lo stesso rimedio suggerito da Phil Haack nel post del blog nella risposta di @George Stocker. –

+0

Sì, sembra così. Non sapevo del bug prima di quello. –

Problemi correlati