2011-08-16 9 views
6

Mam aplikację ASP.NET MVC 3, która rejestruje wpisy krokomierz użytkownika. Użytkownik może wyświetlić wszystkie najnowsze wpisy krokomierza, odwiedzając numer /Pedometer i może filtrować dane według roku, roku/miesiąca lub roku/miesiąca/daty, odwiedzając odpowiednio adresy URL, takie jak /Pedometer/2011, /Pedometer/2011/08 i /Pedometer/2011/08/15.Dlaczego ten parametr trasy jest przypięty do kwerendy?

Utworzyłem dwie zmapowane trasy w Global.asax. Pierwsza trasa, pokazana poniżej, pozwala na różne wzorce adresów URL do filtrowania według daty. Druga trasa (nie pokazana) jest domyślną trasą MVC ASP.NET.

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

Oto moje pytanie. Mam widok, w którym chcę utworzyć łącze formularza: currentUrl?format=csv, które pozwoli użytkownikowi pobrać pozycje krokomierza dla żądanego adresu URL w formacie CSV. Więc jeśli użytkownik odwiedza /Pedometer, link do pobrania będzie do /Pedometer?format=csv. Jeśli użytkownik odwiedza stronę /Pedometer/2011/08, link do pobrania to: /Pedometer/2011/08?format=csv.

Aby stworzyć taki link I dodał zwyczaj Html Helper nazwie DownloadToExcel z następującego kodu:

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 
} 

Kiedy dodać znaczników @Html.DownloadToExcel() moim zdaniem, generuje odnośnik, ale tu właśnie sęk - kiedy użytkownik odwiedza ostatnie wpisy lub wpisy przefiltrowane według roku/miesiąca lub roku/miesiąca/daty, działa zgodnie z oczekiwaniami, ale nie wtedy, gdy użytkownik odwiedza URL filtra rocznego.

Poniższa lista przedstawia URL wizyty użytkownika oraz odpowiedni URL generowane przez niestandardowej HTML Helper:

  • Visiting: /Pedometer - Link do pobrania: /Pedometer?format=csv
  • Visiting: /Pedometer/2011 - Link do pobrania: /Pedometer?year=2011&format=csv
  • Visiting: /Pedometer/2011/08 - Link do pobrania: /Pedometer/2011/08?format=csv
  • Visiting: /Pedometer/2011/08/15 - Link do pobrania: /Pedometer/2011/08/15?format=csv

Dlaczego podczas wizyty /Pedometer/2011 link pobierania /Pedometer?year=2011&format=csv i nie /Pedometer/2011?format=csv? I dlaczego nie działa w tym przypadku, ale działa zgodnie z oczekiwaniami w przypadku roku/miesiąca i roku/miesiąca/daty?

Dzięki

Odpowiedz

6

Ten problem jest najprawdopodobniej spowodowany this bug opisanej przez Phil Haack na swoim blogu. Wystąpił błąd regresji wprowadzony w ASP.NET MVC 3, gdy masz dwa kolejne opcjonalne parametry URL.

+0

To wyjaśnia, dzięki za głowy. :-) –

4

stworzyłem małą MVC 3 aplikację z kodem, który podałeś i mam dokładnie takie samo zachowanie jak opisano.

Jeśli przejdę do http://localhost:51181/pedometer/2011 wygenerowany link będzie http://localhost:51181/Pedometer?year=2011&format=csv.

Ale jeśli jednoznacznie wpisałem nazwę akcji (indeks), renderowałoby to poprawnie.

Zwiedzając http://localhost:51181/pedometer/index/2011 wygeneruje następujący link:

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

wydaje prawidłową trasą nie zawsze jest używany przez metodę rozszerzenia HtmlHelper.

Jeśli dodaję następującą trasę tuż poniżej własnej trasy, ale przed domyślną trasą MVC działa poprawnie.

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

To wygląda tak samo, jak zalecił Phil Haack na blogu w odpowiedzi @George Stockera. –

+0

Tak, wydaje się tak. Nie wiedziałem wcześniej o tym błędzie. –

Powiązane problemy