2010-08-25 3 views
25

Ich habe einen WCF-Dienst, der Seite an Seite mit einer MVC2-Website lebt. Ich würde für den Dienst für meine URL mag so aussehen:MVC2 Routing mit WCF ServiceRoute: Html.ActionLink Rendering falsche Links!

http://localhost/projdir/Service

Die Website MVC in den Kinderschuhen steckt, so dass es nach wie vor von allen Controllern seine vorformulierten hat usw.

Der folgende Code funktioniert bei erster blick in global.asax:

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

    routes.Add(new ServiceRoute("Service", new ServiceHostFactory(), 
       typeof(MyService))); 

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

Der Dienst erscheint genau dort, wo ich beschrieben und funktioniert wie angekündigt. Groß.

Allerdings habe ich gerade bemerkt, dass das Ändern meines Codes auf diese Weise alle meine ActionLink ändert. Zum Beispiel erscheint die Registerkarte „About“ auf dem MVC-Website nun wie folgt aus:

http://localhost/projdir/Service?action=About&controller=Home

Das ist offensichtlich falsch ist (es sollte http://localhost/projdir/Home/About/ sein).

Wenn ich die ServiceRoute Addition unter den Standard MapRoute() Aufruf verschieben, dann bekomme ich einen fehlenden Controller-Fehler. (Tatsächlich bekomme ich einen "StructureMapControllerFactory gab keine Instanz eines Controllers" Fehler, weil ich mit StructureMap verdrahtet bin, duh, es ist kein Controller zu beginnen.)

Interessanterweise scheint es nur zu beeinflussen die Ausgabe von Html.ActionLink(). Ich kann manuell http://localhost/projdir/Home/About/ eingeben und auf die richtige Seite gelangen.

Welcher schrecklich offensichtliche Neulingfehler mache ich?

+0

Möglicherweise ähnliche? http://stackoverflow.com/questions/1470997/html-actionlink-construct-wrong-link-when-a-non-mvc-route--added – roufamatic

Antwort

18

Versuchen Sie, die Service-Route nach der MVC-Route zu verschieben. Um den Fehler "fehlender Controller" zu vermeiden, den Sie zuvor erhalten haben, fügen Sie die MVC-Route mit a Route Constraint hinzu. Diese Route-Constraints können Regex sein - grundsätzlich sollte Ihre Route-Constraint ein beliebiger Controller sein, der nicht "Service" ist. Wenn eine Anfrage nach "Service" angefordert wird, wird es durchfallen und seine WCF Service Route.

+2

Vielen Dank! Ich benutzte 'new {controller ="^{?! Service} "}' als Einschränkung und es funktionierte wie ein Zauber. Verstehst du, warum die Service Route nicht vor der MVC Route sein kann? – roufamatic

+0

Die {controller} und {action} Token sind spezielle Token, die implizit in MVC enthalten sind (Sie können auch eigene Tokens definieren, aber diese sind * immer * da).Wenn Sie zuerst die Serviceroute eingeben, kann sie diese Token nirgends in dem Muster finden, das Sie für Ihre Route definiert haben. Daher werden sie nur als Abfragestrings angehängt. So wird es ziemlich verwirrt, wenn die Serviceroute zuerst ist. Normalerweise möchten Sie Ihre Routen so ordnen, dass zuerst die "spezifischsten" Routen definiert werden. Freut mich zu hören, dass es jetzt für dich funktioniert. –

+5

Danke, das ist hilfreich. Korrektur für zukünftige Googler: Das Muster, das ich verwendet habe, war tatsächlich '^ (?! Service).' ' – roufamatic

3

Eine andere Lösung ist es, die ServiceRoute und überschreiben die GetVirtualPath Methode zu erben null wie here

public class AppServiceRoute : ServiceRoute 
{ 
    public AppServiceRoute(string routePrefix, ServiceHostFactoryBase serviceHostFactory, Type serviceType) 
     : base(routePrefix, serviceHostFactory, serviceType) 
    { 
    } 

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 
    { 
     return null; 
    } 
} 

diese Weise zurückzukehren, Trassierung umkehren nie diese Route für jede Aktion auswählen. Funktioniert wie ein Zauber

8

ich damit aufgelöst:

 routes.MapRoute(
      "Default", // Route name 
      "{controller}/{action}/{id}", // URL with parameters 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional }, 
      new { controller = "^(?!api).*" } 
     ); 
     routes.Add(new ServiceRoute("api", new DataServiceHostFactory(), typeof(dwService))); 

Ich hoffe, das gut für Sie

+0

Ausgezeichnet - Ich habe diese Filter komplett vergessen! DANKE! –

Verwandte Themen