2010-11-02 2 views
0

Я работаю над веб-приложением, и я хочу вызвать веб-сервис через его URL-адрес. Как я могу достичь этого?C# call webservice по url

У меня есть следующий маршрут, зарегистрированный в моем global.asax;

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

И я хочу, чтобы вызвать WebService, в этом случае, чтобы получить последние сообщения из твиттера с помощью URL, аналогичного приведенной ниже;

http://www.domainname.com/Services/Service.svc/GetLatestTweets 

Когда я использую зарегистрированный маршрут, как упоминалось, я получаю сообщение об ошибке со стеком, который я добавил ниже.

[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 

Что мне делать или изменять, чтобы я мог вызвать веб-сервис по его URL-адресу? Я работаю с простым wcf-сервисом

ответ

1

Может быть, я что-то не хватает, но это, кажется, как вы могли бы просто

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

и анализировать удаленный вызов в контроллере, если он более сложен. В маршрутах может быть только один параметр «catchall», но вы можете использовать столько переменных, сколько хотите, и ограничивать/определять их с помощью реализаций IRouteConstraint или шаблонов Regex.

Кроме того, с ответом на комментарий ниже о обработчике .svc против .mvc - вам нечего ограничивать переопределением IHttpHandler. Чтобы сделать это, вам необходимо переопределить метод IRouteHandler in для GetHttpHandler () ... Затем вы можете делать любую необходимую обработку.

+0

Спасибо за ответ :-) У вас есть пример того, как я должен справиться с этим в контроллере? – Rob

+0

Это зависит от того, как вам нужно разбирать строку. Если бы вы построили фасад для api, тогда вы могли бы также реализовать модельное связывание и просто иметь действие контроллера: ActionResult ExecuteServiceCall (сервис ServiceFacade, метод MethodMode, аргументы NameValueCollection) {}, , но , это действительно все зависит от вас и как вы хотите это сделать. Это, наверное, самое лучшее. – smartcaveman

+0

Thnx для ответа, попробует и поработает. Мне еще один вопрос. Почему я не могу использовать что-то вроде этого, чтобы просто игнорировать маршрут? routes.IgnoreRoute ("{ресурс} .svc/{* PathInfo}"); – Rob

3

Вы не можете этого достичь. Расширение .svc уже зарегистрировано с помощью очень другого обработчика, чем MVC, для обработки WCF. Если вы попытаетесь изменить его, служба никогда не будет работать. Возможно, вам потребуется вызвать веб-службу из действия вашего контроллера, которая будет действовать как мост.

+0

Thnx для быстрого ответа. Жаль, что это невозможно, поскольку я подумал об этом, попробует его с контроллером в качестве моста. – Rob