Web API HttpClient PutAsync返回Http 404

时间:2015-03-06 15:28:10

标签: rest asp.net-web-api asp.net-web-api2 dotnet-httpclient

我试图将PUT发送到我的Web API,并且我正在努力构建实际的Http请求。以下是集成测试样本。使用HttpMessageInvoker调用Web API Put可以正常工作,但是我想在测试中使用HttpClient,因为这是我将在业务层中使用的。

    [TestMethod]
    public void Verify_UpdateBudgetData_Http_PUT()
    {
        int budgetId = 1;
        string appId = "DummyApp";
        string userId = "Dummy";
        string value = "400";
        string filterJSON =
                "{dimensionFilter:{\"Demo_Konto\":[\"3000\"],\"Demo_AO\":[\"200\"]},valueSpreadType:{\"Value1\":0}}";

        HttpConfiguration config = new HttpConfiguration();
        Konstrukt.SL.AggregationEngine.WebApiConfig.Register(config, new SL.AggregationEngine.AutofacStandardModule());
        HttpServer server = new HttpServer(config);

        /*this works*/
        using (HttpMessageInvoker client = new HttpMessageInvoker(server))
        {
            using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Put, 
                String.Format("http://localhost/AggregationEngine/UpdateBudgetData/{0}/{1}/{2}/{3}/{4}",
                budgetId, appId, userId, value, filterJSON)))
            using (HttpResponseMessage response = client.SendAsync(request, CancellationToken.None).Result)
            {
                Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, "Wrong http status returned");
            }
        };

        /*this does not work*/
        using (var client = new HttpClient())
        {
            //client.BaseAddress = new Uri("http://localhost");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            var responseMessage =
                client.PutAsync(
                    String.Format("http://localhost/AggregationEngine/UpdateBudgetData/{0}/{1}/{2}/{3}/{4}",
                        budgetId, appId, userId, value, filterJSON), new StringContent("")).Result;
            Assert.AreEqual(HttpStatusCode.OK, responseMessage.StatusCode, "Wrong http status returned");
        }
    }

这是我的WebApiConfig-class

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config, Autofac.Module moduleToAppend)
    {
        config.Routes.MapHttpRoute(
            name: "UpdateBudgetData",
            routeTemplate: "AggregationEngine/{controller}/{budgetId}/{appId}/{userId}/{value}/{filterJSON}",
            defaults: new { filter = RouteParameter.Optional }
        );

        config.Routes.MapHttpRoute(
            name: "GetBudgetAndRefData",
            routeTemplate: "AggregationEngine/{controller}/{budgetId}/{userId}/{filterJSON}",
            defaults: new { filter = RouteParameter.Optional }
        );

        config.EnableCors();
        config.EnableSystemDiagnosticsTracing();

        // Autofac container
        // if not configured here you'll not have dependencies provided to your WebApiControllers when called
        var builder = new ContainerBuilder(); // yes, it is a different container here

        builder.RegisterAssemblyTypes( // register Web API Controllers
            Assembly.GetExecutingAssembly())
                .Where(t =>
                    !t.IsAbstract && typeof(ApiController).IsAssignableFrom(t))
                .InstancePerLifetimeScope();

        // register your graph - shared
        builder.RegisterModule(
            new AutofacStandardModule()); // same as with ASP.NET MVC Controllers

        if (moduleToAppend != null)
        {
            builder.RegisterModule(moduleToAppend);
        }

        var container = builder.Build();

        config.DependencyResolver = new AutofacWebApiDependencyResolver(
            container);
    }

    public static void Register(HttpConfiguration config)
    {
        Register(config, null);
    }
}

如何修复对PutAsync的HttpClient调用?我应该在体内嵌入FilterJSON参数吗?如果是这样,怎么办?我试过了,但是FromBody参数化器是空的......

1 个答案:

答案 0 :(得分:0)

我通过在控制器中使用FromBody标记然后将该参数包装在http请求体中来实现它。一个重要的注意事项是在参数前加上" ="签名以确保控制器正确解释它。我还从路由配置中删除了相同的参数。最后,为了使客户端服务器请求工作,我不得不用httpselfhostserver

替换HttpServer类