如何在 C# 中使用 HttpClient 读取 Web api 响应
Posted
技术标签:
【中文标题】如何在 C# 中使用 HttpClient 读取 Web api 响应【英文标题】:How to read webapi responses with HttpClient in C# 【发布时间】:2016-08-26 09:01:57 【问题描述】:我对 webapi 还很陌生,并且开发了一个小型 webapi,它有一些操作并返回我的自定义类 Response
。
Response
类
public class Response
bool IsSuccess=false;
string Message;
object ResponseData;
public Response(bool status, string message, object data)
IsSuccess = status;
Message = message;
ResponseData = data;
我的带有操作的 webapi
[RoutePrefix("api/customer")]
public class CustomerController : ApiController
static readonly ICustomerRepository repository = new CustomerRepository();
[HttpGet, Route("GetAll")]
public Response GetAllCustomers()
return new Response(true, "SUCCESS", repository.GetAll());
[HttpGet, Route("GetByID/customerID")]
public Response GetCustomer(string customerID)
Customer customer = repository.Get(customerID);
if (customer == null)
throw new HttpResponseException(HttpStatusCode.NotFound);
return new Response(true, "SUCCESS", customer);
//return Request.CreateResponse(HttpStatusCode.OK, response);
[HttpGet, Route("GetByCountryName/country")]
public IEnumerable<Customer> GetCustomersByCountry(string country)
return repository.GetAll().Where(
c => string.Equals(c.Country, country, StringComparison.OrdinalIgnoreCase));
现在我卡住的地方是我不知道如何读取从 webapi 操作返回的响应数据并从我的响应类中提取 json。得到 json 后我怎么能deserialize
那个 json 到客户类。
这是我调用 webapi 函数的方式:
private void btnLoad_Click(object sender, EventArgs e)
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:8010/");
// Add an Accept header for JSON format.
//client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// List all Names.
HttpResponseMessage response = client.GetAsync("api/customer/GetAll").Result; // Blocking call!
if (response.IsSuccessStatusCode)
Console.WriteLine("Request Message Information:- \n\n" + response.RequestMessage + "\n");
Console.WriteLine("Response Message Header \n\n" + response.Content.Headers + "\n");
else
Console.WriteLine("0 (1)", (int)response.StatusCode, response.ReasonPhrase);
Console.ReadLine();
请帮我整理一下我的代码。
如何获取webapi在客户端返回的响应类
如何从响应类中提取 json
如何将json反序列化为客户端的客户类
谢谢
编辑:我使用了这段代码,但仍然出现错误。
var baseAddress = "http://localhost:8010/api/customer/GetAll";
using (var client = new HttpClient())
using (var response = client.GetAsync(baseAddress).Result)
if (response.IsSuccessStatusCode)
var customerJsonString = await response.Content.ReadAsStringAsync();
var cust = JsonConvert.DeserializeObject<Response>(customerJsonString);
else
Console.WriteLine("0 (1)", (int)response.StatusCode, response.ReasonPhrase);
错误是:
Newtonsoft.Json.dll 中出现“Newtonsoft.Json.JsonSerializationException”类型的异常,但未在用户代码中处理
附加信息:无法将当前 JSON 对象(例如 "name":"value")反序列化为类型“WebAPIClient.Response[]”,因为该类型需要 JSON 数组(例如 [1,2,3])正确反序列化。
为什么响应会导致这个错误?
【问题讨论】:
请参阅dotnetperls.com/httpclient 以获取阅读内容的示例。序列化和反序列化可以在这里找到newtonsoft.com/json/help/html/serializingjson.htm 当我以这种方式阅读var customerJsonString = await response.Content.ReadAsStringAsync();
然后将这个符号
存储在 customerJsonString 变量中。我在哪里犯错了?
当您打开浏览器并导航到:localhost:8010/api/customer/GetAll 时会发生什么 - 会返回结果吗? (即在没有您的客户端代码的情况下测试 api)。
我不太清楚你为什么要创建 Response
类。从您的 API 中,您应该能够从存储库中返回对象(或者在本例中为对象列表)。在客户端,您只需通过response.Content.ReadAsStringAsync();
获取响应的字符串(即 JSON),然后您可以使用 JsonConvert 之类的东西将该 Json 字符串反序列化为 C# 对象。您需要在客户端中使用相同的类才能反序列化 - 可能创建了一个共享库或其他东西,以便您可以在两个项目中导入它(只是一个建议)
【参考方案1】:
在客户端,包括阅读内容:
HttpResponseMessage response = client.GetAsync("api/customer/GetAll").Result; // Blocking call!
if (response.IsSuccessStatusCode)
Console.WriteLine("Request Message Information:- \n\n" + response.RequestMessage + "\n");
Console.WriteLine("Response Message Header \n\n" + response.Content.Headers + "\n");
// Get the response
var customerJsonString = await response.Content.ReadAsStringAsync();
Console.WriteLine("Your response data is: " + customerJsonString);
// Deserialise the data (include the Newtonsoft JSON Nuget package if you don't already have it)
var deserialized = JsonConvert.DeserializeObject<IEnumerable<Customer>>(customerJsonString);
// Do something with it
更改您的 WebApi 以不使用您的 Response 类,而是使用 IEnumerable
或 Customer
。使用 HttpResponseMessage
响应类。
您的 WebAPI 应该只需要:
[HttpGet, Route("GetAll")]
public IEnumerable<Customer> GetAllCustomers()
var allCustomers = repository.GetAll();
// Set a breakpoint on the line below to confirm
// you are getting data back from your repository.
return allCustomers;
根据 cmets 中的讨论添加了通用响应类的代码,尽管我仍然建议您不要这样做并避免调用您的类 Response。你应该返回HTTP status codes 而不是你自己的。 200 OK、401 Unauthorised 等。还有this post 关于如何返回 HTTP 状态代码。
public class Response<T>
public bool IsSuccess get; set;
public string Message get; set;
public IEnumerable<T> ResponseData get; set;
public Response(bool status, string message, IEnumerable<T> data)
IsSuccess = status;
Message = message;
ResponseData = data;
【讨论】:
正要这样做,但这节省了我写相同的答案:) 要添加到您的答案中,您还可以使用 Json.NET (Newtonsoft.Json) 将您的 Json 字符串反序列化为 C# 类客户端 - 例如var deserialized = JsonConvert.DeserializeObject<IEnumerable<Customer>>(customerJsonString);
如果我返回包含很多东西的响应类而不是 IEnumerable或者您可以在同一通话中转换
TResponse responseobject = response.Content.ReadAsAsync<TResponse>().Result;
responseJson += "hostResponse: " + JsonParser.ConvertToJson(responseobject);
//_logger.Debug($"responseJson : responseJson", correlationId);
【讨论】:
以上是关于如何在 C# 中使用 HttpClient 读取 Web api 响应的主要内容,如果未能解决你的问题,请参考以下文章
如何在 C# 中使用 HttpClient 存储 cookie?
如何在 C# 中使用 HttpClient 发送文件和表单数据
如何使用 HttpClient 在 ASP.Net C# 中禁用分块传输编码
c#:如何使用 httpclient 发布异步请求并获取流?