locked
Правильная работа с WCF-сервисом из интернета с помощью jQuery $.ajax RRS feed

  • Вопрос

  • У меня есть WCF веб-сервис, который смотрит в интернет. Хостится он на IIS 7, структура: Sites -> MyService (сайт), внутри папка Service, содержащая Service.svc, хотя в IIS не видно последнего файла. В браузере, из интернета, сервис открывается, но при попытке перейти на метод Method1(http://web.ru:1111/Service/Service1.svc/Method1), появляется страница с надписью "Method is not allowed".

    При попытке вызова Method1 с помощью функции $.ajax с веб-страницы, расположенной в интернете, в сетевом мониторе, встроенном в браузер (firebug в Firefox), появляется ошибка 405 - Method is not allowed. Причем Google Chrome все-таки выдает сообщение, которое возвращает метод веб-сервиса, однако в мониторе появляется та же ошибка 405.

    Метод обьявлен так:

    [OperationContract]
    public string Method1(string p1, string p2, string p3, string p4)

    Что и куда нужно добавить или изменить? Может стоит как-то переписать сервис?

    25 января 2012 г. 9:03

Ответы

  • Добрый день.

    У этой ошибки бывает очень много разных причин, для интереса вбейте в поисковик  "Method is not allowed" и увидите сотню вариантов.

    Но давайте по порядку.

    1. С чем я столкнулся лично:

    на новой машине ASP.Net был установлен но не привязан нормально к IIS, проблема решается просто,- идём в папку с .Net Framework ищем файлик  aspnet_regiis.exe и запускаем его из командной строки с такими параметрами aspnet_regiis –i –enable.
    Далее перезапускам IIS и в том конкретном случае помогло.

    2. А самое главное, что то что вы пытаетесь сделать, а именно в какой манере вы пытаетесь это сделать (Ajax) называется - вызов REST сервиса. И тут вам помимо атрибутов OperationContract понадобятся ещё атрибуты WebGet/WebInvoke для методов и атрибут AspNetCompatibilityRequirements для сервиса.

    Выглядеть должно примерно так: 

        [ServiceContract]
        [AspNetCompatibilityRequirements(RequirementsMode
            = AspNetCompatibilityRequirementsMode.Allowed)]
        public class SomeService
        {
            [OperationContract]
            [WebGet(UriTemplate = "SomeService/GetData")]
            public string GetData()
            {
                return "";
            }
        }

     

    Вот тут хороший пример как раз для вашего случая "Consuming WCF REST Services Using jQuery AJAX Callshttp://www.codeproject.com/Articles/128478/Consuming-WCF-REST-Services-Using-jQuery-AJAX-Call

    Ну и теория по теме в целом:

    Введение в службы RESTful с использованием WCF  http://msdn.microsoft.com/ru-ru/magazine/dd315413.aspx

    WCF 4.0: поддержка REST http://www.gotdotnet.ru/blogs/natale/7676/

     




    25 января 2012 г. 10:31
  • > Правильная работа с WCF-сервисом из интернета [...] Метод обьявлен так: [OperationContract] public string Method1(string p1, string p2, string p3, string p4)
     
     
    надо указать WebGet и в UriTemplate указать имена параметров в фигурных скобках.
    примерно так:


    [Data.svc]
    <%@ ServiceHost Service="Test.Provider"
                  Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>
    

     
    [Test.cs]
    using System; 
    using System.ServiceModel; 
    using System.ServiceModel.Web; 
    
    namespace Test 
    { 
         [ServiceContract] 
         public class Provider 
         { 
             [OperationContract] 
             [WebGet(UriTemplate = "/M1/", ResponseFormat = WebMessageFormat.Xml)] 
             public long Now() { return DateTime.Now.Ticks; } 
    
             [OperationContract] 
             [WebGet(UriTemplate = "/M2/{value}={key}")] 
             public string GetSome(string key, string value) 
             { 
                return "hello: " + key + " " + value; 
             } 
         } 
    }
    

     
    [js]
    <script language="javascript"> 
    function Get(uri) { 
       var x = new XMLHttpRequest(); 
       x.open("GET", uri, false, null, null); 
       x.send(); 
       return x.responseText; 
    } 
    </script> 
    

     
    [html]
    <a href="/Data.svc/M1">test1</a>
    <br />
    <a href="/Data.svc/M2/id=123">test2</a>
    
    <button onclick="alert(Get('http://localhost:1799/Data.svc/M1'))">test3</button>
    
     

    p.s.
    пример вызова метода из c# см. здесь
     
     

    • Изменено Malobukv 25 января 2012 г. 11:44 p.s.
    • Предложено в качестве ответа Alexandr Gashper 26 января 2012 г. 6:44
    • Помечено в качестве ответа Abolmasov DmitryModerator 31 января 2012 г. 9:31
    25 января 2012 г. 11:21

Все ответы

  • Добрый день.

    У этой ошибки бывает очень много разных причин, для интереса вбейте в поисковик  "Method is not allowed" и увидите сотню вариантов.

    Но давайте по порядку.

    1. С чем я столкнулся лично:

    на новой машине ASP.Net был установлен но не привязан нормально к IIS, проблема решается просто,- идём в папку с .Net Framework ищем файлик  aspnet_regiis.exe и запускаем его из командной строки с такими параметрами aspnet_regiis –i –enable.
    Далее перезапускам IIS и в том конкретном случае помогло.

    2. А самое главное, что то что вы пытаетесь сделать, а именно в какой манере вы пытаетесь это сделать (Ajax) называется - вызов REST сервиса. И тут вам помимо атрибутов OperationContract понадобятся ещё атрибуты WebGet/WebInvoke для методов и атрибут AspNetCompatibilityRequirements для сервиса.

    Выглядеть должно примерно так: 

        [ServiceContract]
        [AspNetCompatibilityRequirements(RequirementsMode
            = AspNetCompatibilityRequirementsMode.Allowed)]
        public class SomeService
        {
            [OperationContract]
            [WebGet(UriTemplate = "SomeService/GetData")]
            public string GetData()
            {
                return "";
            }
        }

     

    Вот тут хороший пример как раз для вашего случая "Consuming WCF REST Services Using jQuery AJAX Callshttp://www.codeproject.com/Articles/128478/Consuming-WCF-REST-Services-Using-jQuery-AJAX-Call

    Ну и теория по теме в целом:

    Введение в службы RESTful с использованием WCF  http://msdn.microsoft.com/ru-ru/magazine/dd315413.aspx

    WCF 4.0: поддержка REST http://www.gotdotnet.ru/blogs/natale/7676/

     




    25 января 2012 г. 10:31
  • > Правильная работа с WCF-сервисом из интернета [...] Метод обьявлен так: [OperationContract] public string Method1(string p1, string p2, string p3, string p4)
     
     
    надо указать WebGet и в UriTemplate указать имена параметров в фигурных скобках.
    примерно так:


    [Data.svc]
    <%@ ServiceHost Service="Test.Provider"
                  Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>
    

     
    [Test.cs]
    using System; 
    using System.ServiceModel; 
    using System.ServiceModel.Web; 
    
    namespace Test 
    { 
         [ServiceContract] 
         public class Provider 
         { 
             [OperationContract] 
             [WebGet(UriTemplate = "/M1/", ResponseFormat = WebMessageFormat.Xml)] 
             public long Now() { return DateTime.Now.Ticks; } 
    
             [OperationContract] 
             [WebGet(UriTemplate = "/M2/{value}={key}")] 
             public string GetSome(string key, string value) 
             { 
                return "hello: " + key + " " + value; 
             } 
         } 
    }
    

     
    [js]
    <script language="javascript"> 
    function Get(uri) { 
       var x = new XMLHttpRequest(); 
       x.open("GET", uri, false, null, null); 
       x.send(); 
       return x.responseText; 
    } 
    </script> 
    

     
    [html]
    <a href="/Data.svc/M1">test1</a>
    <br />
    <a href="/Data.svc/M2/id=123">test2</a>
    
    <button onclick="alert(Get('http://localhost:1799/Data.svc/M1'))">test3</button>
    
     

    p.s.
    пример вызова метода из c# см. здесь
     
     

    • Изменено Malobukv 25 января 2012 г. 11:44 p.s.
    • Предложено в качестве ответа Alexandr Gashper 26 января 2012 г. 6:44
    • Помечено в качестве ответа Abolmasov DmitryModerator 31 января 2012 г. 9:31
    25 января 2012 г. 11:21
  • Здравствуйте.

    Не забудьте отметить ответ, решивший проблему.

    Спасибо.


    Для связи [mail]
    26 января 2012 г. 6:26
    Модератор