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

查看:83
本文介绍了WCF WebApi的自托管不接受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代码准备端点(同样适用于获取"):

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<string, Machine>... : IResourceService<int, Machine>-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的自托管不接受PUT动词的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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