简体   繁体   English

通过WCF Rest Starter Kit HttpClient应用于PUT时,如何解决WCF Rest MethodNotFound(405)错误

[英]How to resolve WCF Rest MethodNotFound (405) Error when appting to PUT via WCF Rest Starter Kit HttpClient

I have looked at nearly every single WCF Rest PUT/POST issues on SO here and have still been unable to determine why I am unable to PUT or POST to my web service but am able to call a test GetTime method via GET. 我在这里查看了几乎所有关于WCF Rest PUT / POST的问题,并且仍然无法确定为什么我无法PUT或POST到我的Web服务,但是能够通过GET调用测试GetTime方法。

This particular service exchanges custom credential information (username, password and some other information) for a token. 此特定服务交换令牌的自定义凭据信息(用户名,密码和其他一些信息)。 This token information is encrypted and added to the header of subsequent requests to other web services so that username/passwords don't have to be passed around everywhere. 该令牌信息被加密并添加到对其他Web服务的后续请求的标头中,因此不必在任何地方传递用户名/密码。

All web service calls are still treated as stateless, but require this auth header information rather username/passwords to access secured service operations. 所有Web服务调用仍被视为无状态,但需要此auth标头信息而不是用户名/密码来访问受保护的服务操作。

Contract 合同

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

Service Impelementation 服务实施

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

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

Test Code 测试代码

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

The aforementioned GetTime works (just a test method I added). 前面提到的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);
        }
    }

The above put returns a MethodNotAllowed (405) . 上面的put返回一个MethodNotAllowed(405)

Just as another test I added a Mex endpoint to the service, created a new console app and added a 'service reference' to this service. 就像另一个测试一样,我向该服务添加了一个Mex端点,创建了一个新的控制台应用程序,并为此服务添加了“服务参考”。 Using the generated client proxy code, I was able to something similar to.... 使用生成的客户端代理代码,我能够执行类似...的操作。

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

What this suggests is that... 这表明...

  • The web service is hosted in IIS correctly Web服务正确托管在IIS中
  • I am able to consume the service using SOAP client proxy generated code 我能够使用SOAP客户端代理生成的代码使用服务
  • I am able to consume GET requests via more friendly HttpClient / rest toolkit 我可以通过更友好的HttpClient / rest工具包使用GET请求
  • I have tested this get in a browser and it works 我已经在浏览器中测试了它并且可以正常工作
  • For some reason put and other related methods (post, delete. etc) do not work via rest toolkit 由于某些原因,放置和其他相关方法(发布,删除等)无法通​​过rest工具箱使用

Have no idea what is causing this one. 不知道是什么原因造成的。

EDIT 编辑

I also noticed that IIS must have created this web.config in the root of the website where the services are hosted which would seem to be allowing the main HTTP verbs. 我还注意到,IIS必须已经在托管服务的网站的根目录中创建了该web.config,这似乎允许使用主要的HTTP动词。

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

I have also checked in IIS 7 the handler mappings for *.svc and checked that 'all verbs' are enabled. 我还在IIS 7中检查了* .svc的处理程序映射,并检查了“所有动词”是否已启用。

Check that related handler for .svc in IIS is allowed to process HTTP POST, PUT, DELETE. 检查是否允许IIS中有关.svc的相关处理程序处理HTTP POST,PUT,DELETE。 In case of problems with only PUT and DELETE check that your virtual directory is not configured for WebDAV (I think it is some HTTP module). 如果仅PUT和DELETE出现问题,请检查是否未为WebDAV配置虚拟目录(我认为这是某些HTTP模块)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM