【问题标题】:How to resolve WCF Rest MethodNotFound (405) Error when appting to PUT via WCF Rest Starter Kit HttpClient通过 WCF Rest Starter Kit HttpClient 应用到 PUT 时如何解决 WCF Rest MethodNotFound (405) 错误
【发布时间】:2011-04-07 04:00:33
【问题描述】:

我在这里查看了几乎所有关于 SO 的 WCF Rest PUT/POST 问题,但仍然无法确定为什么我无法 PUT 或 POST 到我的 Web 服务,但能够通过 GET 调用测试 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);
        }
    }

上面的 put 返回一个 MethodNotAllowed (405)。

就像另一个测试一样,我向服务添加了一个 Mex 端点,创建了一个新的控制台应用程序并向该服务添加了一个“服务引用”。使用生成的客户端代理代码,我可以做类似的事情......

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

这表明...

  • Web 服务正确托管在 IIS 中
  • 我可以使用 SOAP 客户端代理生成的代码来使用服务
  • 我可以通过更友好的 HttpClient / rest 工具包使用 GET 请求
  • 我已经在浏览器中测试了这个 get,它可以工作
  • 由于某些原因,put 和其他相关方法(发布、删除等)无法通​​过 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>

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

【问题讨论】:

    标签: asp.net wcf rest


    【解决方案1】:

    检查 IIS 中 .svc 的相关处理程序是否允许处理 HTTP POST、PUT、DELETE。如果仅 PUT 和 DELETE 出现问题,请检查您的虚拟目录是否未配置为 WebDAV(我认为它是一些 HTTP 模块)。

    【讨论】:

    • 我检查了 *.svc 的处理程序映射,它被设置为允许所有动词。所以应该没问题。如何检查后者(是否为 WebDAV 配置了虚拟目录?)这是在我的开发机器上的测试环境中,因此托管在 IIS 中的应用程序的位置实际上是我的 SVN 源项目文件夹。可能是权限问题?
    • 这很奇怪,至少 HTTP POST 应该可以正常工作,除非您访问错误的 URL。 WebDav 仅在您安装后使用(它是 IIS 下的 windows 功能)。如果虚拟目录被配置为使用 WebDav,它应该在其模块配置中包含 WebDavModule(在 IIS 管理控制台中检查它)。
    • 好电话,在注意到 WebDav 已安装后,我去“添加删除功能”并从 IIS 中卸载了该模块。它似乎已经解决了我前面提到的 put 问题。明天我将编写更多测试来检查其他 Http 动词类型。我将您的答案标记为已修复,非常感谢您。你能解释为什么 WebDav 会导致这种情况发生,所以我将来知道吗?再次感谢。
    • 我认为 PUT 和 DELETE 是最初用于 WebDAV 的动词。一旦为应用程序安装和配置了 WebDAV(默认),它总是将这些动词作为 WebDAV 请求处理。
    • 我没有安装 WebDav,并且我已经验证我的 .svc 处理程序映射都选择了“所有动词”。我仍然得到“方法不允许”。当我调用删除操作时。
    猜你喜欢
    • 2010-12-07
    • 2011-08-26
    • 2010-11-27
    • 2012-03-06
    • 1970-01-01
    • 2010-12-19
    • 2010-10-06
    • 1970-01-01
    • 2010-11-03
    相关资源
    最近更新 更多