WCF WebApi 的自托管不接受 PUT 动词

标签 wcf wcf-web-api

我使用 WCF WebAPI 组合了一个 HTTP 驱动的 API使用 PUT 动词。当托管在 IIS Express 上托管的 MVC3 项目内部时,一切都按设计运行。

但是,当我进行单元测试时,我偶尔想要测试传输方面,而不仅仅是针对我自己的资源。我的单元测试因 405 - MethodNotAllowed 失败。同样,在 IIS 中托管的完全相同的服务也可以工作(我在配置文件中启用了 PUT 和 DELETE 动词)。

如何让我的测试中使用的“自托管”服务也接受这些动词?

几乎相同的“get”测试有效,所以我不认为以下概念有问题......希望......

[Test]
public void PutNewMachine()
{
    // Create new record to add
    var machine = new Machine
                      {
                          ID = 1,
                          Name = "One",
                          Description = "Machine #1",
                          Location = 1
                      };

    using (var client = new HttpClient())
    {
        using (var request = new HttpRequestMessage(
                                         HttpMethod.Put, 
                                         HOST + "/1"))
        {
            request.Content = new ObjectContent<Machine>(machine);

            using (var response = client.Send(request))
            {
                Assert.AreEqual(
                    HttpStatusCode.Created,
                    response.StatusCode,
                    "New record put should have been acknowledged "
                                    + "with a status code of 'Created'");
            }
        }
    }
}

在测试设置中,我使用以下 Autofac 代码准备端点(这同样适用于“Get”):

var builder = new ContainerBuilder();
builder
    .Register(c => new FakeDatabase())
    .As<IDatabase>()
    .SingleInstance();
builder
    .Register(c => new GenericRepository<Machine>(c.Resolve<IDatabase>()))
    .As<IResourceRepository<Machine>>();
builder
    .Register(c => new MachineService(c.Resolve<IResourceRepository<Machine>>()))
    .As<MachineService>();
Container = builder.Build();
Scope = Container.BeginLifetimeScope();

host = new HttpServiceHost(typeof(MachineService), HOST);
host.AddDependencyInjectionBehavior<MachineService>(Container);
host.Open();

我的服务在以下接口(interface)中定义:

[ServiceContract]
public interface IResourceService<in TKey, TResource>
{
    [WebGet(UriTemplate = "{key}")]
    TResource Get(TKey key);

    [WebInvoke(Method = "PUT", UriTemplate = "{key}")]
    TResource Put(TKey key, TResource resource);

    [WebInvoke(Method = "POST")]
    TResource Post(TResource resource);

    [WebInvoke(Method = "DELETE", UriTemplate = "{key}")]
    void Delete(TKey key);
}

因此,例如,如果我有一个 MachineService,它会实现该接口(interface)(class MachineService : IResourceService<string, Machine>... : IResourceService<int, Machine> 都已被试用 - Get = OK,Put = Nothing。

编辑:我似乎在 InternalServerError 和 MethodNotAllowed 错误之间跳来跳去 - 仅在使用自托管时。我已确保我作为用户有权打开端口(Win7 + 非管理员),但结果加上我选择的端口似乎可以预测 Get 的功能。 “Post”似乎也有类似的问题! :-(

EDIT2:界面现已更改为可用!

[ServiceContract]
public interface IResourceService<in TKey, TResource>
{
    [WebGet(UriTemplate = "{key}")]
    TResource Get(TKey key);

    [WebInvoke(Method = "PUT", UriTemplate = "{key}")]
    TResource Put(HttpRequestMessage<TResource> resourceRequest, TKey key);

    [WebInvoke(Method = "POST", UriTemplate = "{key}")]
    TResource Post(HttpRequestMessage<TResource> resourceRequest, TKey key);

    [WebInvoke(Method = "DELETE", UriTemplate = "{key}")]
    void Delete(TKey key);
}

最佳答案

当我更改方法签名以接受 HttpRequestMessage 请求而不是 T 本身时,执行 PUT 或 POST 对我有用。

关于WCF WebApi 的自托管不接受 PUT 动词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6398134/

相关文章:

wcf - 通过 .config 文件设置自定义 WCF 绑定(bind)行为 - 为什么这不起作用?

asp.net-mvc - 将 WCF 服务添加到 ASP.NET MVC 项目

asp.net-mvc - MVC4 WebAPI 原因短语?

odata - WCF WebApi 启用 OData 查询支持

asp.net-mvc-3 - 在 MVC3 中使用 WebApi

C# WCF Web API + JSONP

WCF 全局 (.asax) 行为

c# - WCF,svcutil.exe : How to properly match or configure web service client code?

.net - 在 Silverlight 中维护 DB 对象的内存缓存的最佳方法

asp.net-mvc - 您如何返回自定义 503 消息?