通过传递简单和复杂的参数来调用 web api

san*_*029 3 .net c# asp.net-web-api dotnet-httpclient asp.net-web-api-routing

获取在控制器中找不到 http 资源或操作的错误消息。在 web api 中,我有一个 from body 和 from uri 参数。

[HttpPost]        
public IHttpActionResult processfields(
    [FromUri]string field1,
    [FromUri]string field2, 
    [FromBody] string field3, 
    [FromUri]string field4
){...}
Run Code Online (Sandbox Code Playgroud)

在客户端中,我想通过执行以下操作来调用 web api--

using (var client = new HttpClient())
{
    //set up client
    client.BaseAddress = new Uri(Baseurl);
    client.DefaultRequestHeaders.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));


     var values = new Dictionary<string, string>();
     values.Add("field1", field1);
     values.Add("field2", field2);
     values.Add("field3", field3);
     values.Add("field4", filed4);


     var jsonString = JsonConvert.SerializeObject(values);
     try
     {

         HttpResponseMessage Res = client.PostAsync("api/home/processfields", new StringContent(jsonString, Encoding.UTF8, "application/json")).Result;
         var result = Res.Content.ReadAsStringAsync();
     }
}
Run Code Online (Sandbox Code Playgroud)

调试时,它执行上面的最后一行,但没有任何反应,错误消息说--

{"Message":"未找到与请求 URI ' http://xxx.xxx.xx.xx:1234/api/home/processfields '匹配的 HTTP 资源。","MessageDetail":"未找到操作与请求匹配的控制器 'home'。"}

我的 webapi.config 有

// Web API routes
config.MapHttpAttributeRoutes();


config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);
Run Code Online (Sandbox Code Playgroud)

Cod*_*ler 5

field1,field2field4参数应该在 Url 中,而不是在请求正文中。这就是请求 Url 应如下所示的原因:http://xxx.xxx.xx.xx:1234/api/home/processfields?field1=value1&field2=value2&field4=value4

field3从身体反序列化。但是,由于它是字符串参数,因此不应将请求正文构建为 JSON 对象:

{
  "field3": "value3"
}
Run Code Online (Sandbox Code Playgroud)

但作为 JSON 字符串:

"value3"
Run Code Online (Sandbox Code Playgroud)

这是应该可以工作的调整后的客户端代码:

using (var client = new HttpClient())
{
    //set up client
    client.BaseAddress = new Uri(Baseurl);
    client.DefaultRequestHeaders.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    var requestUri = new Uri($"api/home/processfields?field1={HttpUtility.UrlEncode(field1)}&field2={HttpUtility.UrlEncode(field2)}&field4={HttpUtility.UrlEncode(field4)}", UriKind.Relative);
    var content = new StringContent($"\"{field3}\"", Encoding.UTF8, "application/json");
    var response = await client.PostAsync(requestUri, content);
    var result = await response.Content.ReadAsStringAsync();
}
Run Code Online (Sandbox Code Playgroud)