【问题标题】:Post (or put) request with uri parameter not working when calling with HttpClient使用 HttpClient 调用时使用 uri 参数发布(或放置)请求不起作用
【发布时间】:2019-09-16 12:55:20
【问题描述】:

在尝试在 c# 中创建一个 Web API 并通过 c# HttpClient 使用它时,我已经编写了一些控制器和客户端调用并且工作正常,但是现在我需要使用两个参数调用一个 Post 方法,一个简单的值(long)直接在URL[FromURI]中,另外一个是body中传入的复杂类型。

我想我可以简化答案,假设我只想调用一个帖子或在 URL 中传递一个简单的参数。

首先,让我们看看我的网络服务器映射配置:

HttpConfiguration config = new HttpConfiguration(); config.Routes.MapHttpRoute(
                    name: "DefaultWebApi",
                    routeTemplate: "api/{controller}/{id}",
                    defaults: new { id = RouteParameter.Optional });

这就是我的 Put 控制器:

 [HttpPut]
 public IHttpActionResult PutComandas([FromUri] long ticket)
 {
 ...
 }

我可以使用 PostMan 和诸如 localhost:8200/api/Comandas?ticket=9 之类的 URL 毫无问题地调用它,但我找不到方法与 HttpClient 的调用,对我来说很奇怪,我不能像使用 get 请求那样简单地调用(在 PostMan 中)到 localhost:8200/api/Comandas/9 ......就像路由配置正在为gets工作,但不适用于puts/posts...无论如何,真正的问题是:我找不到使用HttpClient进行正确put调用的方法。我正在尝试:

HttpClient client = new HttpClient();
var response = client.PutAsync("localhost:8200/api/Comandas?ticket=9", null).Result;

但我收到了 Not Found 响应。

注意:我可以毫无问题地使用复杂的主体参数调用 Put/Post。

【问题讨论】:

  • 你可能想做client.PutAsync("http://localhost:8200/api/Comandas?ticket=9", null);
  • 出于稳定性原因请勿使用.Result see here...here
  • 是的,我是新手,但我读到了一些关于不要使用 .Result 的内容,无论如何,它不起作用

标签: c# asp.net dotnet-httpclient


【解决方案1】:

更简洁的方法是使用字典并作为 FormUrlEncodedContent 传递

var url = "localhost:8200/api/Comandas";
var parameters = new Dictionary<string, string> { { "ticket", "9" } };
var encodedContent = new FormUrlEncodedContent(parameters);

var response = await client.PutAsync(url, encodedContent);

另外作为旁注,HttpClient 应该只实例化一次然后重新使用:https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=netframework-4.7.1#Remarks

编辑:用户现在已经澄清他们正在寻找 Uri 参数和 Body 参数。继续上面的代码:

AddQueryString 可通过

Microsoft.Owin.Infrastructure.WebUtilities.AddQueryString()

或者如果使用 .NET Core

Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString()
var url = "localhost:8200/api/";
// Query string parameters
var parameters = new Dictionary<string, string>(){ { "ticket", "9" } };

// Create json for body
var content = new JObject(yourBodyObject);

// SetupHttpClient
client.BaseAddress = new Uri(url);

// This is the important bit
var requestUri = QueryHelpers.AddQueryString("Comandas", parameters);

var request = new HttpRequestMessage(HttpMethod.Put, requestUri);
// Setup headers for Content-Type
request.Headers.Add("Accept", "application/json");
// Add body content
request.Content = new StringContent(
    content.ToString(),
    Encoding.UTF8,
    "application/json"
);

// Send the request
client.SendAsync(request);

【讨论】:

  • 但您的解决方案使用像 url 内容一样编码的正文内容。我的目标是能够调用类似的东西: Post([FromUri] long ticket, [FromBody] ComplexType details)... 我可以用 PostMan 调用 api 来做到这一点
猜你喜欢
  • 2013-12-01
  • 2017-05-25
  • 1970-01-01
  • 1970-01-01
  • 2016-04-26
  • 1970-01-01
  • 2018-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多