PUT 動詞を使用するWCF WebAPIを使用して、HTTP 駆動型 API をまとめました。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();
私のサービスは、次のインターフェースで定義されています。
[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.
EDIT : InternalServerError と MethodNotAllowed エラーの間でバウンスしているようです - セルフホスティングを使用している場合のみ。ユーザーとして、ポートを開く権限があることを確認しました (Win7 + 非管理者) が、その結果とポートの選択は、Get に対して予測可能な機能のようです。「投稿」にも同様の問題があるようです!:-(
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);
}