Вызов клиенту WCF Restful «Удаленный сервер возвратил неожиданный ответ: (405) Метод не разрешен». - PullRequest
0 голосов
/ 05 февраля 2011

Я новичок в WCF. Я создал WCF-службу отдыха в VS2010 (приложение службы WCF). Он был ориентирован на Framework 4.0. Я размещал этот сервис на локальном IIS с установленным пулом приложений для платформы 4.0. Когда я вызываю методы appl из браузера или фиддлера, они работают нормально. Теперь я создал клиентскую консоль на основе. Когда я вызываю любой метод из клиента, я получаю следующее исключение связи:

** удаленный сервер возвратил неожиданный ответ: (405) Метод не разрешен. **

Файл интерфейса службы:

namespace MyService

{

[ServiceContract]
public interface ITestService
{


    [WebGet(UriTemplate = "GetDateTime")]
    [OperationContract]
    string GetDateTime();

    [WebGet(UriTemplate = "GetName")]
    [OperationContract]
    string GetName();

}

}

Класс, реализующий вышеуказанный интерфейс:

namespace MyService

{

 public class TestService : ITestService
    {
        public string GetDateTime()
        {
            return DateTime.Now.ToString();
        }

    public string GetName()
    {
        return "MY name is KingKong";
    }
}

}

Файл Web.config:

  <system.serviceModel>
<services>
  <service behaviorConfiguration="ServiceBehavior" name="MyService.TestService">
    <endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="" contract="MyService.ITestService">

    </endpoint>
  </service>
</services>
<behaviors>
  <endpointBehaviors>
    <behavior name="web">
      <webHttp />
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="ServiceBehavior">
      <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
      <serviceMetadata httpGetEnabled="true" />
      <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
      <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

TestService.svc

<% @ ServiceHost Language = "C #" Debug = "true" Service = "MyService.TestService" CodeBehind = "TestService.svc.cs"%>

Клиентский app.config:

<system.serviceModel>
    <behaviors>
        <endpointBehaviors>
            <behavior name="">
                <webHttp />
            </behavior>
        </endpointBehaviors>
    </behaviors>
    <client>
        <endpoint address="http://localhost/BestService/TestService.svc"
            binding="webHttpBinding" bindingConfiguration="" contract="MyService.ITestService"
            name="MyClientConfig" kind="" endpointConfiguration="" />
    </client>
</system.serviceModel>

Клиентская программа вызывает класс прокси

 static void Main(string[] args)
    {
        TestServiceClient proxy = null;
        try
        {
            proxy = new TestServiceClient();

            Console.WriteLine("Test 1: List all products");
            string sdatetime = proxy.GetName();

            Console.WriteLine("Datetime: {0}", sdatetime);

            Console.WriteLine();

            // Disconnect from the service
            proxy.Close();


        }
        catch (CommunicationException cex)
        {

            if (cex.InnerException != null)
            {
                Console.WriteLine("{0}", cex.InnerException.Message);
            }
            else
            {
                Console.WriteLine("General exception: {0}", cex.Message);
            }
        }
        catch (Exception e)
        {
            if (e.InnerException != null)
            {
                Console.WriteLine("{0}", e.InnerException.Message);
            }
            else
            {
                Console.WriteLine("General exception: {0}", e.Message);
            }
        }

        Console.WriteLine("Press ENTER to finish");
        Console.ReadLine();
    }

Я добавил служебную ссылку в приложение, и файл Reference.cs имеет следующий частичный код:

namespace MyClient.MyService {

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="MyService.ITestService")]
public interface ITestService {

    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ITestService/GetDateTime", ReplyAction="http://tempuri.org/ITestService/GetDateTimeResponse")]
    string GetDateTime();

    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ITestService/GetName", ReplyAction="http://tempuri.org/ITestService/GetNameResponse")]
    string GetName();
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface ITestServiceChannel : MyClient.MyService.ITestService, System.ServiceModel.IClientChannel {
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class TestServiceClient : System.ServiceModel.ClientBase<MyClient.MyService.ITestService>, MyClient.MyService.ITestService {

    public TestServiceClient() {
    }

    public TestServiceClient(string endpointConfigurationName) : 
            base(endpointConfigurationName) {
    }

    public TestServiceClient(string endpointConfigurationName, string remoteAddress) : 
            base(endpointConfigurationName, remoteAddress) {
    }

    public TestServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : 
            base(endpointConfigurationName, remoteAddress) {
    }

    public TestServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
            base(binding, remoteAddress) {
    }

    public string GetDateTime() {
        return base.Channel.GetDateTime();
    }

    public string GetName() {
        return base.Channel.GetName();
    }
}

}

Пожалуйста, помогите мне, так как я потратил почти 2 дня, пытаясь выяснить проблему в клиенте

Спасибо

1 Ответ

0 голосов
/ 10 февраля 2011

VS2010 не может сгенерировать прокси для службы RESTFUL, как для службы на основе SOAP.Поэтому решение состоит в том, чтобы написать свой собственный прокси-класс, который наследуется от класса ClientBase, и использовать канал для вызова веб-методов службы.

...