2010-11-02 10 views
0

Je travaille sur une application web et je veux appeler un webservice via son URL. Comment puis-je atteindre cet objectif?C# appeler webservice par url

J'ai la route suivante enregistrée dans mon global.asax;

routes.MapRoute(
       "ServiceHandler", 
       "{*path}/{*.svc}", 
       new { Url = "Services/Service.svc/GetLatestTweets" } 
       ); 

Et je veux appeler le webservice, dans ce cas pour obtenir les derniers messages de twitter par une url similaire à celui ci-dessous; Lorsque j'utilise la route enregistrée comme mentionné, j'obtiens une erreur avec la stackstrace que j'ai ajouté ci-dessous.

[ArgumentException: A catch-all parameter can only appear as the last segment of the route URL. 
Parameter name: routeUrl] 
    System.Web.Routing.RouteParser.Parse(String routeUrl) +3823656 
    System.Web.Routing.Route..ctor(String url, IRouteHandler routeHandler) +24 
    System.Web.Mvc.RouteCollectionExtensions.MapRoute(RouteCollection routes, String name, String url, Object defaults, Object constraints, String[] namespaces) +86 
    System.Web.Mvc.RouteCollectionExtensions.MapRoute(RouteCollection routes, String name, String url, Object defaults, Object constraints) +28 
    System.Web.Mvc.RouteCollectionExtensions.MapRoute(RouteCollection routes, String name, String url, Object defaults) +18 
    CMS.Presentation.FrontEnd.Framework.CMSApplication.RegisterRoutes(RouteCollection routes) in C:\Projects\Website\Web.Presentation\FrontEnd\Framework\CMSApplication.cs:62 
    CMS.Presentation.FrontEnd.Framework.CMSApplication.Application_Start() in C:\Projects\Website\Web.Presentation\FrontEnd\Framework\CMSApplication.cs:80 

[HttpException (0x80004005): A catch-all parameter can only appear as the last segment of the route URL. 
Parameter name: routeUrl] 
    System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext context, HttpApplication app) +3988565 
    System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +191 
    System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +325 
    System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +407 
    System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +375 

[HttpException (0x80004005): A catch-all parameter can only appear as the last segment of the route URL. 
Parameter name: routeUrl] 
    System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +11529072 
    System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +141 
    System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +4784373 

Que dois-je faire ou changer afin que je puisse appeler le webservice par son URL? Je travaille avec un simple service wcf

Répondre

1

Peut-être que je manque quelque chose, mais il semble que vous pourriez

 routes.MapRoute(
      "ServiceHandler", 
      "Services/{service}.svc/{*path}", 
      new { controller = "services", action = "ParseAndExecuteServiceCall" service = "TwitterService", path = "GetLatestTweets" } 
      ); 

et analyser le appel à distance dans le contrôleur, si elle est plus complexe. Vous ne pouvez avoir qu'un paramètre "catchall" dans les routes, mais vous pouvez utiliser autant de variables que vous le souhaitez et les restreindre/les définir avec des implémentations IRouteConstraint ou des modèles Regex. En outre, en réponse au commentaire ci-dessous sur le gestionnaire .svc vs .mvc - Il n'y a rien pour vous limiter de surcharger le IHttpHandler Pour ce faire, vous devez remplacer la méthode IRouteHandler in pour GetHttpHandler () ... Ensuite, vous pouvez faire le traitement que vous voulez.

+0

Merci pour la réponse :-) Avez-vous un exemple comment je dois gérer cela dans le contrôleur? – Rob

+0

Cela dépend des services quant à la façon dont vous devez analyser la chaîne. Si vous deviez construire une façade pour l'api, alors vous pourriez mettre en œuvre un modèle de liaison ainsi, et juste le look d'action du contrôleur comme: ActionResult ExecuteServiceCall (service ServiceFacade, MethodInfo ServiceMethod, les arguments de NameValueCollection) {}, mais , tout dépend de vous et de la façon dont vous voulez le faire. C'est probablement la meilleure chose. – smartcaveman

+0

Thnx pour la réponse, va essayer de le résoudre. Une autre question s'est produite à moi. Pourquoi ne puis-je pas utiliser quelque chose comme ça pour simplement ignorer la route? routes.IgnoreRoute ("{ressource} .svc/{* pathInfo}"); – Rob

3

Vous ne pouvez pas réaliser cela. L'extension .svc est déjà enregistrée avec un gestionnaire très différent de MVC afin de traiter WCF. Si vous essayez de le changer, le service ne fonctionnera jamais. Vous devrez peut-être appeler le service Web à partir de votre action de contrôleur, qui servira de pont.

+0

Thnx pour la réponse rapide. Dommage que ce ne soit pas possible comme je l'ai pensé, je vais l'essayer avec un contrôleur comme pont – Rob