2009-09-24 10 views
7

Mam tutaj aplikację z połączeniem webform i mvc. Podam routing poniżej:Html.ActionLink konstruuje niewłaściwy link, gdy dodana zostanie trasa inna niż mvc

 routes.Add("AspxRoute", new Route("Upload/New", new WebFormRouteHandler<Page>("~/Uploads.aspx"))); 

     routes.MapRoute(
      "Default",            // Route name 
      "{controller}/{action}/{id}",       // URL with parameters 
      new { controller = "Home", action = "Index", id = "" } // Parameter defaults 
     ); 

Tak więc wirtualna ścieżka do "Upload/New" faktycznie odwzorowuje stronę formularza internetowego aspx.

Ale moim problemem jest to, że Html.ActionLink ("Test", "Kontroler", "Action"), teraz czyni

// Nowe? Prześlij Controller = Kontroler & Action = Akcja

Po zapoznaniu się z kodem źródłowym MVC, rozumiem, że dzieje się tak, ponieważ połączenie ActionLink wywołuje RouteCollection.GetVirtualPath(requestContext, routeName, mergedRouteValues), gdzie parametr routeName ma wartość null. I w jakiś sposób domyślnie używa się trasy AspxRoute do skonstruowania adresu URL. Próbowałem dodać inną trasę przed "AspxRoute", ale wygląda na to, że zawsze jest ona domyślną pozycją non-mvc.

Jak działa RouteCollection.GetVirtualPath zachowanie, gdy parametr routeName ma wartość null? I dlaczego zachowuje się w ten sposób w moim przypadku?

Jak skonstruować poprawny adres URL? Czy muszę napisać nowe rozszerzenie Htmlhelper?

Cheers

Odpowiedz

3

Spróbuj:

<%=Html.RouteLink("Test", "Default", new {controller = "Controller", action = "Action"})%> 

Korzystanie RouteLink zamiast actionlink pozwala określić trasę, którą chcesz użyć, która w tym przypadku jest domyślne odwzorowanie trasy MVC w przeciwieństwie do zwyczaju jednym Dodałeś.

+0

Hi dzięki. Wiem, że działa RouteLink, ale to tylko drobna niedogodność! Wszystkie magiczne struny. Dlaczego ActionLink nie działa. –

+0

Zawiera tylko jeden ciąg niż ActionLink, a pierwotne pytanie brzmiało "Jak utworzyć poprawny adres URL?". Powodem, dla którego jest to konieczne, jest to, że twój WebFormRouteHandler zapewnia "poprawne" dopasowanie do trasy, a ponieważ jest dodawany przed domyślną trasą w RouteTable, jest on zwracany jako pierwszy. Ale w każdym razie dodałem kolejną odpowiedź, która może być bardziej do twoich potrzeb. –

6

Alternatywną opcją byłoby dodanie niestandardowego ograniczenia do WebFormRoute (s). Na przykład można utworzyć implementację obiektu IRouteConstraint, aby dopasować RouteDirection.IncomingRequest, a następnie użyć go, aby zapewnić, że trasa jest ignorowana przez trasy generowane przez serwer (takie jak ActionLink), ale nadal jest używana przez żądania generowane przez klienta. Coś jak:

public class IncomingOnlyRouteConstraint: IRouteConstraint 
{ 
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     if (routeDirection == RouteDirection.IncomingRequest) 
     { 
      return true; 
     } 
     return false; 
    } 
} 

a następnie dodać ograniczenie do trasy:

routes.Add("AspxRoute", new Route("Upload/New", null, 
          new RouteValueDictionary() { {"WebFormsConstraint", new IncomingOnlyRouteConstraint()} }, 
          new WebFormRouteHandler<Page>("~/Uploads.aspx"))); 

Oczywiście może wolisz, aby dodać swój własny styl przymusu, ten jest dość ograniczenie na trasie, która implementuje go , ale jest to tylko jeden z przykładów, w jaki sposób można rozwiązać problem.

+0

Dzięki, użyłem tej odpowiedzi, aby naprawić inne moje pytanie. – JTew

+0

Świetnie! dokładnie to, czego szukałem! – gsobocinski

+1

Żałuję, że mam tylko jeden upominek, by dać tę odpowiedź. –

2

Ponadto: Upewnij się, że trasa domyślna jest pozycją LAST w tabeli routingu. To kolejny prosty sposób, by skończyć z rodzajem linku akcji html, który otrzymujesz.

+0

Pytanie od tak dawna wciąż otrzymuję odpowiedzi :-) jeśli spojrzysz na kod, który dołączyłem, jest to ostatni wpis w tabeli tras. MVC.net przeszedł długą drogę, może wszystko się zmieniło, nie mam pojęcia! –

1

Doświadczyłem tego samego, gdy trasy pracowały poprawnie "w ruchu", ale Html.ActionLink() wybierało złą trasę. Pracowałem wokół niego dodając ograniczenie trasę tak, że controller musi być pusty:

var constraints = new RouteValueDictionary() 
{ 
    { "controller", string.Empty } 
}; 

routes.Add(new Route("sso/server", null, constraints, new OpenIDServerRouteHandler())); 

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

Ponieważ „kontroler” wartość trasa jest ograniczona do zera, wezwanie do actionlink() kończy się ignorując trasą. Mam nadzieję, że to pomoże komuś!

1

wymusić domyślne trasy nie mieć Kontroler:

var routeDefaults = new RouteValueDictionary() { { "controller", null } }; 
routes.Add("RouteName", new Route("some/path", routeDefaults, new SomeHandler())); 
Powiązane problemy