2012-03-01 11 views
6

Buduję prosty raport aplikacji sieciowej do wyświetlania raportów przy użyciu ASP.NET MVC3 + WebForms. Same raporty są renderowane przez formant WebForms ReportViewer ASP.NET, ale chciałbym użyć ASP.NET MVC do utworzenia wpisu parametru.ASP.NET MVC + WebForms - konflikt trasy

Chciałbym, aby wszystkie żądania były zgodne z domyślnym schematem routingu "~/{controller}/{action}/{parameters}", z wyjątkiem żądań dla ~/Report, które powinny przejść do raportu renderującego WebForm. Jak to zrobić?

Rozszerzając trochę ..

Mam dwie trasy w Global.asax.cs - domyślny i jeden dla strony WebForms.

public static void RegisterRoutes(RouteCollection routes) 
{ 
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

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

    routes.MapPageRoute("report-rendering", "Report", "~/Render.aspx"); 
} 

adresy URL dostać wygenerowana w porządku, ale problem polega na tym, że gdy nadejdzie żądanie, pierwsza trasa zjada również adresy URL do drugiego, tj ~/Report?id=7 próbuje wywołać metodę Index na ReportController (który nie istnieje).

Jeśli zmienić go tak, że „Raport renderowania” droga jest przed „default” trasy, tak jak poniżej:

public static void RegisterRoutes(RouteCollection routes) 
{ 
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

    routes.MapPageRoute("report-rendering", "Report", "~/Render.aspx"); 

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

Teraz wzywa do Html.ActionLink() czynią niepoprawne adresy URL, czyli

`@Html.ActionLink("Report list", "Index", "ReportList")` 

Renders

`http://localhost:49910/Report?action=Index&controller=ReportList` 

Moje bieżące obejście stawia Default trasę pierwszy, dodając ograniczenie regex do ignorowania żądań dla kontrolera "Report", tak jak:

routes.MapRoute(
    "Default", // Route name 
    "{controller}/{action}/{id}", // URL with parameters 
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults 
    new { controller = @"(?!report$).*" } 
); 

To nie jest czyste. Ponownie, jaki jest właściwy sposób na zrobienie tego?

Ponadto, jeszcze nie zdecydowałem, w jaki sposób przekazuję parametry do formularza renderowania: Mogę użyć obu parametrów zapytania lub POST je. Zgaduję, że parametry zapytania są bardziej elastyczne. Jaka jest tutaj najlepsza praktyka?

EDIT:

Badając odpowiedź przez @LeftyX, wydaje się, że znalazłem odpowiedź. Cytując P. Haack od jego rozdziału Routing w Professional ASP.NET MVC 3 (nazwanych tras, rozdział 9, strona 233):

... Użyj nazwy dla wszystkich swoich tras i zawsze podczas generowania adresów używać nazwy trasy . W większości przypadków, pozwalając Routingowi wybrać trasę, której chcesz użyć do wygenerowania adresu URL, naprawdę pozostawiasz ją przypadkowi, co nie jest czymś, co dobrze pasuje do obsesyjno-kompulsywnego maniaka kontroli. Podczas generowania adresu URL generalnie, dokładnie wiesz, do której trasy chcesz prowadzić łącze, więc równie dobrze możesz podać nazwę.

Wspomniana sekcja omawia sytuację bardzo podobną do tej, którą opisałem.

Ale ponieważ Html.ActionLink() nie ma przeciążenia z parametrem nazwy trasy, oznacza to, że nie mogę niezawodnie używać go w dowolnym miejscu w całej aplikacji, jeśli ma taką trasę?

Odpowiedz

1

To najlepsze rozwiązanie, jakie wymyśliłem.
Mam zarejestrowany moją drogę z MapPageRoute (Wrzuciłem mój raport stronę pod folderze o nazwie Raporty)

public static void RegisterRoutes(RouteCollection routes) 
{ 
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

    routes.MapPageRoute(
      "report-rendering", 
      "Report/{id}", 
      "~/Reports/Report.aspx" 
     ); 

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

stworzyłem mój link używając RouteLink tak można określić trasy do używania:

@Html.RouteLink("Report list", "report-rendering", new { id = 7 }) 

i mogę dostać id w moją stronę Webform tak:

protected void Page_Load(object sender, EventArgs e) 
{ 
    var id = Page.RouteData.Values["id"] as string; 
} 

Mam nadzieję, że to pomaga.

UPDATE:

Utworzyłem metodę rozszerzenia aby ułatwić Ci życie:

public static class ExtensionMethods 
{ 
    public static MvcHtmlString WebFormActionLink(this HtmlHelper htmlHelper, string linkText, string ruoteName, object routeValues) 
    { 
     var helper = new UrlHelper(htmlHelper.ViewContext.RequestContext); 

     var anchor = new TagBuilder("a"); 
     anchor.Attributes["href"] = helper.RouteUrl(routeName, routeValues); 
     anchor.SetInnerText(linkText); 
     return MvcHtmlString.Create(anchor.ToString()); 
    } 
} 

Najlepiej byłoby użyć actionlink zamiast WebFormActionLink ale mam problemy z podpisami i nie jestem ekspertem w tym zakresie.

+0

Dzięki za odpowiedź. Widzę, co tu zrobiłeś. Ponieważ dodałeś parametr {id}, wywołania .RouteLink() bez podania wartości dla {id} nie pasują już do trasy. Jednak generowanie trasy podczas określania parametru id będzie zgodne z tą trasą. To: @ Html.ActionLink ("Strona 1", "Strona", "Strona główna", nowy {id = 1}, pusty) Wygeneruje to: http: // localhost: 49910/Report/1? Action = Strona i kontroler = Strona główna Co nie jest tym, czego można się spodziewać, prawda? –

+0

@ghostskunks: Wiem. Obawiam się, że musisz używać RouteLink do generowania linków do WebForms lub możesz spróbować rozszerzyć ActionLink. – LeftyX

+0

@ghostskunks: Próbowałem coś złożyć (zaktualizowana odpowiedź), ale, jak powiedziałem, nie jestem ekspertem. To tylko pomysł. – LeftyX

Powiązane problemy