我试图从Web API使用HttpClient POST一个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,但我在这一步上被挂断了。


当前回答

当我做这份工作时,我想用一个回答来回答所有问题,作为对所有人和我自己的提醒:

根据Serez的回答,HttpContent派生类列表如下 https://stackoverflow.com/a/42380027/914284

HttpClient PostAsync有一些背景,这取决于你正在工作的上下文!

在情况下,您可以根据希望发送到服务器的类型发布数据 服务器上下文等待它,如下所示

[HttpPost] 公共异步特别工作组< iasult > Submit(我的模型) [HttpPost] 公共异物特别工作组< iasult > Submit([FromForm]我的模型) [HttpPost] 公共异物特别工作组< iasult > Submit([身体]我的模型)

当写入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(写入头)

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");

其他回答

最简单的方法是使用StringContent,使用JSON对象的JSON表示形式。

httpClient.Post(
    "",
    new StringContent(
        myObject.ToString(),
        Encoding.UTF8,
        "application/json"));

谢谢你pomber

var result = client.PostAsync(url, content).Result;

我使用

var result = await client.PostAsync(url, content);

因为结果使应用程序锁定高请求

我也遇到过同样的问题

var content = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json"); 

gave

“400个坏请求”

单独序列化JsonObject并在StringContent()中传递字符串解决了我的问题,不需要设置Encoding。use UTF8分开。

当我做这份工作时,我想用一个回答来回答所有问题,作为对所有人和我自己的提醒:

根据Serez的回答,HttpContent派生类列表如下 https://stackoverflow.com/a/42380027/914284

HttpClient PostAsync有一些背景,这取决于你正在工作的上下文!

在情况下,您可以根据希望发送到服务器的类型发布数据 服务器上下文等待它,如下所示

[HttpPost] 公共异步特别工作组< iasult > Submit(我的模型) [HttpPost] 公共异物特别工作组< iasult > Submit([FromForm]我的模型) [HttpPost] 公共异物特别工作组< iasult > Submit([身体]我的模型)

当写入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(写入头)

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");

根据你的. net版本,你也可以使用HttpClientExtensions。PostAsJsonAsync方法。

https://msdn.microsoft.com/en-us/library/system.net.http.httpclientextensions.postasjsonasync.aspx