WCF Restful 客户端抛出“远程服务器返回意外响应:(405) 不允许方法。”

发布于 2024-10-15 19:02:13 字数 6301 浏览 5 评论 0原文

我是 WCF 的新手。我在VS2010中创建了一个WCF Restful服务(WCF服务appl)。它是针对 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 天的时间试图找出客户端中的问题,

谢谢

I am a newbie at WCF. I created a WCF restful service in VS2010 (WCF service appl). It was targeted for Framework 4.0. I hosted this service on local IIS with appl pool set for framework 4.0. When I call the appl methods from browser or fiddler, they work fine. Now, I created a client console based. When I call any method from client I get the following Communication Exception:

** remote server returned an unexpected response: (405) Method Not Allowed.**

Service Interface file:

namespace MyService

{

[ServiceContract]
public interface ITestService
{


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

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

}

}

Class that implements the above interface:

namespace MyService

{

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

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

}

Web.config file:

  <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" %>

Client 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>

Client program calling proxy class

 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();
    }

I added a service reference to the application and the Reference.cs file has following partial code:

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();
    }
}

}

Please help me as I have spent nearly 2 days trying to figure out the problem in the client

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冰魂雪魄 2024-10-22 19:02:13

VS2010 无法像基于 SOAP 的服务那样为 RESTFUL 服务生成代理。因此,解决方案是编写自己的代理类,该代理类继承自 ClientBase 类,并使用 Channel 来调用服务的 Web 方法。

VS2010 doesnt have the ability to generate a proxy for a RESTFUL service as it does for a SOAP based service. So the solution is write your own proxy class which inherits from the ClientBase class and use the Channel to call the web methods of the service.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文