c# - 在 C# 控制台应用程序中使用 HttpClient 使用 WEB API

标签 c# rest api asp.net-web-api2

我使用 MySQL 数据库在 Visual Studio 2015 中创建了一个 Web API。 API 运行完美。

所以我决定做一个控制台client我可以在其中使用我的网络服务(Web API)的应用程序。客户端代码基于HttpClient ,并且在 API 中我使用了 HttpResponse 。现在,当我运行控制台应用程序代码时,我什么也得不到。下面是我的代码:

类别

class meters_info_dev
{
    public int id { get; set; }
    public string meter_msn { get; set; }
    public string meter_kwh { get; set; }
}

该类与我的 Web API 模型类相同:

Web API 中的模型

namespace WebServiceMySQL.Models
{

using System;
using System.Collections.Generic;

public partial class meters_info_dev
{
    public int id { get; set; }
    public string meter_msn { get; set; }
    public string meter_kwh { get; set; }
}

控制台应用程序代码

static HttpClient client = new HttpClient();

static void ShowAllProducts(meters_info_dev mi)
{
    Console.WriteLine($"Meter Serial Number:{mi.meter_msn}\t Meter_kwh: {mi.meter_kwh}", "\n");
}

static async Task<List<meters_info_dev>> GetAllRecordsAsync(string path)
{
    List<meters_info_dev> mID = new List<meters_info_dev>();
    HttpResponseMessage response = await client.GetAsync(path);
    if (response.IsSuccessStatusCode)
    {
        mID = await response.Content.ReadAsAsync<List<meters_info_dev>>();
    }
    else
    {
        Console.WriteLine("No Record Found");
    }
    return mID;
}

static void Main()
{
    RunAsync().Wait();
}

static async Task RunAsync()
{
    client.BaseAddress = new Uri("http://localhost:2813/");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    var m = await GetAllRecordsAsync("api/metersinfo/");

    foreach(var b in m)
    {
        ShowAllProducts(b);
    }
}

在我的 API 中,我有 3 GET方法在单个 Controller 下,所以我为它们创建了不同的路由。它们的 URL 也不同。

  1. http://localhost:2813/api/metersinfo/将返回所有记录

在调试代码时,我发现List<meters_info_dev> mID = new List<meters_info_dev>();为空:

enter image description here

虽然响应是302 Found ,网址也是正确的:

enter image description here

更新 1

根据建议,我做了以下工作:

using (var client = new HttpClient())
{
    List<meters_info_dev> mID = new List<meters_info_dev>();
    HttpResponseMessage response = await client.GetAsync(path);
    if (response.IsSuccessStatusCode)
    {
        mID = await response.Content.ReadAsAsync<List<meters_info_dev>>();
    }
    else
    {
        Console.WriteLine("No Record Found");
    }
   return mID;
}

当我运行应用程序时,出现异常“提供了无效的请求 URI。请求 URI 必须是绝对 URI,或者必须设置 BaseAddress。”

更新2

我添加了一段新代码:

using (var cl = new HttpClient())
{
    var res = await cl.GetAsync("http://localhost:2813/api/metersinfo");
    var resp = await res.Content.ReadAsStringAsync();
}

在响应中我得到了所有记录:

enter image description here

我不知道为什么它不能与其他逻辑一起工作以及问题是什么。我还阅读了问题Httpclient consume web api via console app C#Consuming Api in Console Application .

任何帮助将不胜感激。

最佳答案

该代码需要大量工作。

您突出显示的行将始终为空,因为这是您初始化变量的位置。您想要的是运行代码,直到从调用中返回结果。

首先,确保您的 api 确实有效,您可以在浏览器中调用所需的 GET 方法并看到结果。

 using (var client = new HttpClient())
 {
      var result = await client.GetAsync("bla");
      return await result.Content.ReadAsStringAsync();
 } 

这当然是一个示例,因此请将其替换为您的特定数据和方法。

现在,当您仅因为您的 response.IsSuccessStatusCode 为 false 而检查结果时,并不意味着没有记录。意思就是调用彻底失败了。空列表的成功结果与完全失败不同。

如果您想查看返回的内容,您可以稍微更改一下代码:

if(response.IsSuccessStatusCode)
        {
            var responseData = await response.Content.ReadAsStringAsync();
            //more stuff
        }

在此行上放置一个断点并查看实际返回的内容,然后您担心将结果强制转换到对象列表中。只需确保您返回的结果与在浏览器中测试调用时获得的结果相同即可。

<--------------------------------------------> 编辑后的更多详细信息。

为什么不简化一下你的代码。

例如,一次性设置请求的 URL :

 using (var client = new HttpClient())
            {
                var result = await client.GetAsync("http://localhost:2813/api/metersinfo");
                var response = await result.Content.ReadAsStringAsync();
                 //set debug point here and check to see if you get the correct data in the response object
            }

您今天的第一件事是查看是否可以访问该网址并获取数据。 一旦获得正确的响应,您就可以担心基地址了。一旦你有了一个工作样本,就从简单的开始,然后从那里开始逐步完善。

<----------------- 新编辑 ----------------> 好的,既然您收到了响应,您可以使用 Newtonsoft.Json 之类的工具将字符串序列化回对象列表。这是一个 NuGet 包,您可能已经安装了它,或者只是添加它。

在文件顶部添加 using 语句。

using Newtonsoft.Json;

那么你的代码就会变成这样:

using (var client = new HttpClient())
 {
      var result = await client.GetAsync("bla");
      var response = await result.Content.ReadAsStringAsync();
      var mID = JsonConvert.DeserializeObject<List<meters_info_dev>>(response);
 } 

此时您应该拥有对象列表,并且可以执行您需要的任何其他操作。

关于c# - 在 C# 控制台应用程序中使用 HttpClient 使用 WEB API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46444678/

相关文章:

c# - 如何设置 ASP :Menu with CSS 的样式

c# - 在 WebBrowser 控件中禁止保存/打开对话框

azure - 查找带注释的标签的 ObjectId

java - Jersey 测试框架给出空指针异常

如果为空,则设置为新实例的 C# 扩展方法

c# - ListView 列是否有可显示的最大长度?

android - 无法在 Android 中调用 REST API

ios - Alamofire HTTP 请求失败

c++ - 返回类型更改时如何弃用函数 C++

c# - 在 C# 中访问 Lync/Skype for Business 对话