WCF WebApi's 自托管不接受 PUT 动词 [英] WCF WebApi's Self-Hosting not accepting PUT verbs

查看:21
本文介绍了WCF WebApi's 自托管不接受 PUT 动词的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have put together a HTTP driven API using the WCF WebAPI that uses the PUT verb. When hosted inside of an MVC3 project that is hosted upon IIS Express, everything works as designed.

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

However, when I unit-test I'm occasionally wanting to test the transport aspects rather than just against my own resources. My unit-tests fail with a 405 - MethodNotAllowed. Again, exactly the same service hosted in IIS works (where I enabled the PUT and DELETE verbs in the configuration file).

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

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

The almost identical 'get' tests work, so I'm not expecting the concept of the following to be at fault.. hopefully...

[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"):

In the setup to the test, I'm preparing the end-points using the following Autofac code (and again this works for the '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();

我的服务定义在如下界面:

My service is defined in the following 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,它实现了接口(class MachineService : IResourceService... : IResourceService; 已经过试验 - Get = OK,Put = Nothing.

So, for example, if I have a MachineService, it implements the interface (both class MachineService : IResourceService<string, Machine> and ... : IResourceService<int, Machine> have been trialled - Get = OK, Put = Nothing.

编辑:我似乎在 InternalServerError 和 MethodNotAllowed 错误之间跳来跳去 - 仅在使用自托管时.我已确保作为用户,我有权打开端口(Win7 + 非管理员),但结果加上我选择的端口似乎对 Get 有用.发布"似乎也有类似的问题!:-(

EDIT: I seem to be bouncing between InternalServerError and MethodNotAllowed errors - only when using the self-hosting. I have ensured that I, as a user, have rights to open the port (Win7 + non-admin) but the results of that plus my choice of ports seems predicable functional for Get. "Post" seems to be having similar issues! :-(

EDIT2:界面现已更改为有效!

EDIT2: Interface has now changed to which works!

[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 对我有用.

Doing PUT or POST works for me when I change the method signature to accept a HttpRequestMessage request instead of T itself.

这篇关于WCF WebApi&amp;#39;s 自托管不接受 PUT 动词的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆