Web API HttpClient PutAsync 返回 Http 404

Web API HttpClient PutAsync returning Http 404

我正在尝试将 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 参数为空...

我通过在控制器中使用 FromBody 标记并将该参数包装在 http 请求正文中来使其工作。一个重要的注意事项是在参数前加上“=”号,以确保它被控制器正确解释。我还从路由配置中删除了相同的参数。最后,为了使客户端到服务器的请求正常工作,我不得不将 HttpServer Class 替换为 httpselfhostserver