【问题标题】:Receiving JSON data back from HTTP request从 HTTP 请求接收 JSON 数据
【发布时间】:2012-06-07 08:45:52
【问题描述】:

我有一个正常工作的 Web 请求,但它只是返回 OK 状态,但我需要我要求它返回的对象。我不确定如何获取我请求的 json 值。我是使用对象 HttpClient 的新手,是否有我遗漏的属性?我真的需要返回的对象。感谢您的帮助

拨打电话 - 运行正常返回 OK 状态。

HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept
  .Add(new MediaTypeWithQualityHeaderValue("application/json"));
var responseMsg = client.GetAsync(string.Format("http://localhost:5057/api/Photo")).Result;

api获取方法

//Cut out alot of code but you get the idea
public string Get()
{
    return JsonConvert.SerializeObject(returnedPhoto);
}

【问题讨论】:

  • 你是问使用.NET 4.5 HttpClient类时如何获取响应内容?

标签: c# httpwebrequest


【解决方案1】:

如果您指的是 .NET 4.5 中的 System.Net.HttpClient,您可以使用 HttpResponseMessage.Content 属性作为 HttpContent 派生对象获取 GetAsync 返回的内容。然后,您可以使用HttpContent.ReadAsStringAsync 方法将内容读取到字符串中,或​​者使用ReadAsStreamAsync 方法将内容读取为流。

HttpClient 类文档包括以下示例:

  HttpClient client = new HttpClient();
  HttpResponseMessage response = await client.GetAsync("http://www.contoso.com/");
  response.EnsureSuccessStatusCode();
  string responseBody = await response.Content.ReadAsStringAsync();

【讨论】:

  • 尚未对此进行测试,但 EnsureSuccessStatusCode 的文档显示“如果 Content 不为 null,此方法还将调用 Dispose 以释放托管和非托管资源。”所以你不妨先阅读内容。 msdn.microsoft.com/en-us/library/…
  • 没有理由。正如 Reflector 所证明的那样,EnsureSuccessStatusCode 仅在状态码不成功时才会处理,就在抛出异常之前。还有一个文档文本有点混乱的情况。
  • 为什么不只是client.GetStringAsync(...)?那不是在 2012 年。如果响应不是 200,他们都会抛出异常,对吗?
  • @Simon_Weaver 因为这不是问题 - OP 询问如何从响应中读取字符串。有个不同。您无法使用 GetStringAsync 检查响应,这意味着您不知道响应消息是什么。如果返回 3xx 响应,您可能不想抛出。如果返回限制错误,您可能希望重试而不抛出异常。
  • @Simon_Weaver 有很多 很多 方法可以拨打电话 - 为什么不 GetAsync<T> 呢?或者 GetStreamAsync 并将流传递给 Json.NET,避免临时字符串?同样,最好先使用GetAsync 然后访问内容对象
【解决方案2】:

@Panagiotis Kanavos 的回答为基础,这里有一个工作方法作为示例,它还将响应作为对象而不是字符串返回:

using System.Text;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json; // Nuget Package

public static async Task<object> PostCallAPI(string url, object jsonObject)
{
    try
    {
        using (HttpClient client = new HttpClient())
        {
            var content = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json");
            var response = await client.PostAsync(url, content);
            if (response != null)
            {
                var jsonString = await response.Content.ReadAsStringAsync();
                return JsonConvert.DeserializeObject<object>(jsonString);
            }
        }
    }
    catch (Exception ex)
    {
        myCustomLogger.LogException(ex);
    }
    return null;
}

请记住,这只是一个示例,您可能希望将 HttpClient 用作共享实例,而不是在 using 子句中使用它。

【讨论】:

  • 小心 httpclient 不会像 using 语句那样处理
  • 由于await立即返回,有可能if (response != null)在post调用完成之前就执行了吗?
  • 我看不出有什么区别,即使您说“将响应作为对象而不是字符串返回。”,如果是这种情况,您为什么要使用 JsonConvert 执行额外的手动步骤.DeserializedObject(),即在客户端收到字符串后将其转换为对象(作为字符串)。
  • @Nishant:公平的问题。在Task 完成之前,该方法中的await 之后的代码 不会执行。然后会为这个方法中的代码分配一个线程继续执行。这行:if (response != null) 将不会执行,直到前一行上等待的Task 完成。
【解决方案3】:

从 Microsoft System.Net.Http.Json 安装此 nuget 包。它包含扩展方法。

然后添加using System.Net.Http.Json

现在,您将能够看到这些方法:


所以你现在可以这样做了:

await httpClient.GetFromJsonAsync&lt;IList&lt;WeatherForecast&gt;&gt;("weatherforecast");

来源:https://www.stevejgordon.co.uk/sending-and-receiving-json-using-httpclient-with-system-net-http-json

【讨论】:

  • 这是目前最简单的方法。
  • 当有人使用非getter方法时,还有一个从接收到的响应内容中提取JSON的辅助方法——ReadFromJsonAsync
【解决方案4】:

我认为最短的方法是:

var client = new HttpClient();
string reqUrl = $"http://myhost.mydomain.com/api/products/{ProdId}";
var prodResp = await client.GetAsync(reqUrl);
if (!prodResp.IsSuccessStatusCode){
    FailRequirement();
}
var prods = await prodResp.Content.ReadAsAsync<Products>();

【讨论】:

  • 只是想到 id add ReadAsAsync 是一种扩展方法。您需要对 .net 4+ 使用 System.Net.Http.Formatting,对 .net 核心使用 Microsoft.AspNet.WebApi.Client。让这个工作。
【解决方案5】:

我平时做的,类似回答一:

var response = await httpClient.GetAsync(completeURL); // http://192.168.0.1:915/api/Controller/Object

if (response.IsSuccessStatusCode == true)
    {
        string res = await response.Content.ReadAsStringAsync();
        var content = Json.Deserialize<Model>(res);

// do whatever you need with the JSON which is in 'content'
// ex: int id = content.Id;

        Navigate();
        return true;
    }
    else
    {
        await JSRuntime.Current.InvokeAsync<string>("alert", "Warning, the credentials you have entered are incorrect.");
        return false;
    }

“model”是您的 C# 模型类。

【讨论】:

    【解决方案6】:

    通过以下方式对我来说效果很好 -

    public async Task<object> TestMethod(TestModel model)
        {
            try
            {
                var apicallObject = new
                {
                    Id= model.Id,
                    name= model.Name
                };
    
                if (apicallObject != null)
                {
                    var bodyContent = JsonConvert.SerializeObject(apicallObject);
                    using (HttpClient client = new HttpClient())
                    {
                        var content = new StringContent(bodyContent.ToString(), Encoding.UTF8, "application/json");
                        content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                        client.DefaultRequestHeaders.Add("access-token", _token); // _token = access token
                        var response = await client.PostAsync(_url, content); // _url =api endpoint url
                        if (response != null)
                        {
                            var jsonString = await response.Content.ReadAsStringAsync();
    
                            try
                            {
                                var result = JsonConvert.DeserializeObject<TestModel2>(jsonString); // TestModel2 = deserialize object
                            }
                            catch (Exception e){
                                //msg
                                throw e;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return null;
        }
    

    【讨论】:

      【解决方案7】:

      以下代码用于访问您的 HttpResponseMessage 并从 HttpContent 中提取您的响应。

      string result = ret.Result.Content.ReadAsStringAsync().Result;
      

      根据您的业务将您的 json 转换为结构 在我的例子中,BatchPDF 是一个复杂的对象,它由结果变量填充。

      BatchPDF batchJson = JsonConvert.DeserializeObject<BatchPDF>(result);
      
      return batchJson;
      

      【讨论】:

        猜你喜欢
        • 2013-12-30
        • 1970-01-01
        • 2015-02-02
        • 1970-01-01
        • 2015-05-07
        • 1970-01-01
        • 1970-01-01
        • 2014-07-26
        相关资源
        最近更新 更多