我正在尝试使用来自 Web API 的 HttpClient
发布 JsonObject
。我不太确定如何解决这个问题,并且在示例代码中找不到太多。
这是我到目前为止所拥有的:
var myObject = (dynamic)new JsonObject();
myObject.Data = "some data";
myObject.Data2 = "some more data";
HttpClient httpClient = new HttpClient("myurl");
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = httpClient.Post("", ???);
我想我需要将我的 JsonObject
转换为 StreamContent
,但我已经挂断了这一步。
使用新版本的 HttpClient
并且没有 WebApi
软件包,它将是:
var content = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json");
var result = client.PostAsync(url, content).Result;
或者,如果您想要它 async
:
var result = await client.PostAsync(url, content);
最简单的方法是使用带有 JSON 对象的 JSON 表示形式的 StringContent
。
httpClient.Post(
"",
new StringContent(
myObject.ToString(),
Encoding.UTF8,
"application/json"));
根据您的 .NET 版本,您还可以使用 HttpClientExtensions.PostAsJsonAsync
方法。
https://msdn.microsoft.com/en-us/library/system.net.http.httpclientextensions.postasjsonasync.aspx
如果使用 Newtonsoft.Json:
using Newtonsoft.Json;
using System.Net.Http;
using System.Text;
public static class Extensions
{
public static StringContent AsJson(this object o)
=> new StringContent(JsonConvert.SerializeObject(o), Encoding.UTF8, "application/json");
}
例子:
var httpClient = new HttpClient();
var url = "https://www.duolingo.com/2016-04-13/login?fields=";
var data = new { identifier = "username", password = "password" };
var result = await httpClient.PostAsync(url, data.AsJson())
JsonConvert.SerializeObject
使用 DateTimes ISO 8601 的问题种类:本地或 UTC...hackered.co.uk/articles/…
我没有足够的声誉来对 pomber 的答案添加评论,所以我发布了另一个答案。使用 pomber 的方法,我不断收到来自我将 JSON 请求发布到(Visual Studio 2017,.NET 4.6.2)的 API 的“400 Bad Request”响应。最终问题被追溯到由 StringContent() 生成的“Content-Type”标头不正确(请参阅 https://github.com/dotnet/corefx/issues/7864)。
tl;博士
使用 pomber 的答案和额外的一行来正确设置请求的标题:
var content = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json");
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var result = client.PostAsync(url, content).Result;
StringContent
构造函数中传递 "application/json"
,因为它是在生成的 content.Headers.ContentType
属性上显式设置的。但是,我还没有在代码中对此进行测试。
application/json; charset=utf-8
。
vbnet中的代码:
dim FeToSend as new (object--> define class)
Dim client As New HttpClient
Dim content = New StringContent(FeToSend.ToString(), Encoding.UTF8,"application/json")
content.Headers.ContentType = New MediaTypeHeaderValue( "application/json" )
Dim risp = client.PostAsync(Chiamata, content).Result
msgbox(risp.tostring)
希望这有帮助
我花了几个小时试图解决这个问题。但是@anthls anwser 救了我的皮肤。
var data = new StringContent(JsonConvert.SerializeObject(new
{
abc = "jsjs",
xyz = "hhhh"
}));
data.Headers.ContentType = new MediaTypeHeaderValue("application/json"); // <-
var response = client.PostAsync(url, data).Result;
谢谢你,但是为了
var result = client.PostAsync(url, content).Result;
我用了
var result = await client.PostAsync(url, content);
因为 Result 使应用程序锁定高请求
在做这项工作时,我想一次性回答所有问题,作为对所有人和我自己的说明:
根据 Serez 的回答 HttpContent 派生类列表如下https://stackoverflow.com/a/42380027/914284
HttpClient PostAsync 有一些背景,具体取决于您处理的上下文!
在服务器上下文等待它的情况下,您可以按要发送到服务器的类型发布数据,如下所示
[HttpPost] public async Task
在编写 FromForm 或 Body 时,它作为 FromForm 工作。 FromBody 需要 json 内容,否则它需要 KeyValuePairs 作为行。它们都有一些实现,如下所示:
对于 FromForm:我使用了扩展名
public static class HelperExtensions
{
public static FormUrlEncodedContent ToFormData(this object obj)
{
var formData = obj.ToKeyValue();
return new FormUrlEncodedContent(formData);
}
public static IDictionary<string, string> ToKeyValue(this object metaToken)
{
if (metaToken == null)
{
return null;
}
// Added by me: avoid cyclic references
var serializer = new JsonSerializer { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
if (metaToken is not JToken token)
{
// Modified by me: use serializer defined above
return ToKeyValue(JObject.FromObject(metaToken, serializer));
}
if (token.HasValues)
{
var contentData = new Dictionary<string, string>();
foreach (var child in token.Children().ToList())
{
var childContent = child.ToKeyValue();
if (childContent != null)
{
contentData = contentData.Concat(childContent)
.ToDictionary(k => k.Key, v => v.Value);
}
}
return contentData;
}
var jValue = token as JValue;
if (jValue?.Value == null)
{
return null;
}
var value = jValue?.Type == JTokenType.Date ?
jValue?.ToString("o", CultureInfo.InvariantCulture) :
jValue?.ToString(CultureInfo.InvariantCulture);
return new Dictionary<string, string> { { token.Path, value } };
}
}
对于 FromBody:使用任何 json 转换器库 Newtonsoft 或 microsoft
using Newtonsoft.Json;
var jsonString = JsonConvert.SerializeObject(obj);
两者都需要根据需求定义内容类型,例如 json (Write to header)
request.Headers.Accept.Clear();
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
或其他用法
using (var content = new StringContent(JsonConvert.SerializeObject(answer), System.Text.Encoding.UTF8, "application/json"))
{
var answerResponse = await client.PostAsync(url, content);
//use await it has moved in some context on .core 6.0
}
如果您应该在上下文中使用授权,您也可以提供如下授权:
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "Your Oauth token");
我遇到了同样的问题,即 var content = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json");给了“400 Bad Request” Serilizing jsonObject 并在 StringContent() 中传递字符串为我解决了问题,无需单独设置 Encoding.UTF8。
using
的任何人:aspnetmonsters.com/2016/08/2016-08-27-httpclientwrongvar content = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json")
,我还必须设置content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
。有关详细信息,请参阅下面的答案。