代码之家  ›  专栏  ›  技术社区  ›  Joshua Hayes

如何解决通过wcf rest starter kit httpclient应用于放置时wcf rest methodnotfound(405)错误

  •  2
  • Joshua Hayes  · 技术社区  · 14 年前

    在这里,我已经研究了几乎每个单独的wcf rest-put/post问题,并且仍然无法确定为什么我不能将其放入或发布到我的Web服务,但是能够通过get调用一个test-gettime方法。

    这个特定的服务交换令牌的自定义凭证信息(用户名、密码和一些其他信息)。这个令牌信息被加密并添加到其他Web服务的后续请求的头中,这样就不必在任何地方传递用户名/密码。

    所有Web服务调用仍然被视为无状态的,但需要此身份验证头信息而不是用户名/密码来访问安全的服务操作。

    合同

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

    服务实施

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

    上述看跌期权返回 不允许的方法(405) .

    正如另一个测试一样,我向服务添加了一个MEX端点,创建了一个新的控制台应用程序,并向该服务添加了一个“服务引用”。使用生成的客户机代理代码,我可以得到类似于…

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

    这意味着…

    • Web服务正确托管在IIS中
    • 我能够使用SOAP客户机代理生成的代码使用该服务
    • 我能够通过更友好的httpclient/rest工具包使用get请求
    • 我在浏览器中测试过这个GeT,它工作正常
    • 出于某种原因,Put和其他相关方法(Post、Delete。等等)不要通过REST工具包工作

    不知道是什么导致了这个。

    编辑

    我还注意到,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>
    

    我还签入了IIS7中*.svc的处理程序映射,并检查了“所有谓词”是否已启用。

    1 回复  |  直到 14 年前
        1
  •  1
  •   Ladislav Mrnka    14 年前

    检查IIS中.svc的相关处理程序是否允许处理http post、put、delete。如果只有Put和Delete出现问题,请检查您的虚拟目录是否配置为WebDAV(我认为它是一些HTTP模块)。