2010-09-02 57 views
2

我已经看着所以这里几乎每一个WCF休息PUT/POST问题,并仍无法确定为什么我不能将PUT或POST发布到我的Web服务,但能够通过GET调用测试GetTime方法。appting通过WCF休息初学者工具包HttpClient的投入时,如何解决WCF休息MethodNotFound(405)错误

这种特殊的服务交流定制凭证信息(用户名,密码以及其他一些信息)的令牌。这个令牌信息被加密并被添加到对其他Web服务的后续请求的头部,以便用户名/密码不必到处传递。

所有Web服务呼叫仍然视为无国籍人,但需要相当的用户名/密码,此AUTH头信息访问受保护的服务操作。

合同

[ServiceContract(Namespace = "")] 
public interface IUserService 
{ 
    [WebInvoke(Method = "PUT", UriTemplate = "users/{username}/session")] 
    [WebHelp(Comment = "Creates a new session for the specified username")] 
    [OperationContract] 
    AuthToken PutSession(string username, CustomCredential credential); 
    ... 

    [WebInvoke(Method = "GET", UriTemplate = "time")] 
    [WebHelp(Comment = "Test method; returns the time")] 
    [RequireAuthToken] 
    [OperationContract] 
    DateTime GetTime(); 
} 

服务Impelementation

public class UserService : IUserService 
{ 
    #region UserService Members 
    public AuthToken PutSession(string username, CustomCredential credential) 
    { 
     // ... 
    } 

    public DateTime GetTime() 
    { 
     return DateTime.Now; 
    } 
} 

测试代码

[Fact] 
    public void When_Authenticated_And_Getting_Time_Expect_200_Status() 
    { 
     // arrange 
     using (var client = Get_HttpClient_With_AuthHeaders()) { 

      // act 
      var result = client.Get("time"); 

      // assert 
      Assert.Equal(HttpStatusCode.OK, result.StatusCode); 
     } 
    } 

的前面提到的GetTime工程(只是我添加的测试方法)。

[Fact] 
    public void When_PuttingSession_Expect_AuthToken_Is_Returned() 
    { 
     // arrange 
     using (var client = Get_HttpClient_With_No_Auth_Headers()) { 

      var cred = new CustomCredential("test", "password", 1); 
      var content = HttpContentExtensions.CreateDataContract<CustomCredential>(cred); 

      // act 
      HttpResponseMessage response = client.Put("users/test/session", content); 

      // assert 
      response.EnsureStatusIsSuccessful(); 
      Assert.Equal(HttpStatusCode.Created, response.StatusCode); 
      var authToken = response.Content.ReadAsDataContract<AuthToken>(); 
      Assert.NotNull(authToken); 
     } 
    } 

上面放返回MethodNotAllowed(405)

正如另一个测试我添加了一个MEX终结的服务,创造了一个新的控制台应用程序,并增加了“服务引用”这项服务。使用生成的客户端代理代码,我能类似的东西....

IUserServiceClient client = new IUserServiceClient(); 
CustomCredential cred = ... 
AuthToken token = client.PutSession("test_username", cred); 

什么这种情况表明...

  • 的Web服务托管在IIS正确
  • 我能够使用SOAP客户端代理生成的代码
  • 我能够通过更友好的HttpClient/rest工具包消费GET请求
  • 我已经测试了这个获得在浏览器中,它w兽人
  • 出于某种原因把和其他相关方法(后删除。等)不工作通过休息工具包

不知道是什么造成这一个。

编辑

我还注意到,IIS必须在网站,服务托管这似乎可以使主HTTP动词的根已经创造了这个web.config文件。

<?xml version="1.0" encoding="UTF-8"?> 
<configuration> 
    <system.webServer> 
     <security> 
      <requestFiltering> 
      <verbs> 
       <add verb="PUT" allowed="true" /> 
       <add verb="GET" allowed="true" /> 
       <add verb="POST" allowed="true" /> 
       <add verb="DELETE" allowed="true" /> 
      </verbs> 
      <fileExtensions> 
       <add fileExtension=".svc" allowed="true" /> 
      </fileExtensions> 
     </requestFiltering> 
     </security> 
    </system.webServer> 
</configuration> 

我也在IIS 7中检查了* .svc的处理程序映射,并检查是否启用了“所有动词”。

回答

1

检查IIS中.svc的相关处理程序是否允许处理HTTP POST,PUT,DELETE。如果只有PUT和DELETE存在问题,请检查您的虚拟目录是否未配置为WebDAV(我认为它是某个HTTP模块)。

+0

我检查了* .svc的处理程序映射,并将其设置为允许所有动词。所以这应该是好的。如何检查后者(是否为WebDAV配置虚拟目录?)这是在我的开发机器上的测试环境中,因此托管在IIS中的应用程序的位置实际上是我的SVN源项目文件夹。权限问题可能吗? – 2010-09-02 08:02:38

+0

这很奇怪,至少HTTP POST应该没有任何问题,除非你访问错误的URL。 WebDav仅在安装时使用(​​它是IIS下的Windows功能)。如果将虚拟目录配置为使用WebDav,则应在其模块配置中包含WebDavModule(在IIS管理控制台中检查它)。 – 2010-09-02 09:08:19

+0

良好的调用,注意到已安装WebDav后,我去'添加删除功能',并从IIS中卸载该模块。它似乎解决了我前面提到的问题。我会写更多的测试来明天检查其他的Http动词类型。 我正在将您的答案标记为已修复,所以非常感谢。你能解释为什么WebDav导致这种情况发生,所以我知道将来?再一次,谢谢。 – 2010-09-02 11:44:09