在c#console应用程序中使用HttpClient来使用WEB API

时间:2017-09-27 09:47:32

标签: c# rest api visual-studio-2015 asp.net-web-api2

我使用web API数据库在visual studio 2015中创建了MySQL。 API工作正常。所以我决定创建一个控制台Client应用程序,我可以在其中使用我的Web服务(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方法。所以我为他们创造了不同的路线。此外,URL对他们来说也是不同的。

  1. http://localhost:2813/api/metersinfo/ // It will return all records
  2. 在调试代码时,我发现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;
            }
    

    当我运行应用程序时,我得到异常An invalid request URI was provided. The request URI must either be an absolute URI or BaseAddress must be set.

    更新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

    我不知道为什么它不能与其他逻辑一起工作,问题是什么。我也看过文章12

    任何帮助都将受到高度赞赏

1 个答案:

答案 0 :(得分:1)

代码需要相当多的工作。

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

首先,确保您的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
        }

在这一行放置一个断点,看看你实际得到了什么,然后你担心将结果转换为你的对象列表。只需确保您在浏览器中测试呼叫时获得相同的内容。

&LT; -------------------------------&GT; 编辑后的更多细节。

为什么不稍微简化代码。

例如,只需一次设置请求的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
            }

您当天的第一个订单是查看是否可以点击网址并获取数据。 一旦得到正确的响应,您可以担心基地址。一旦你有了工作样本,就开始简单并从那里开始工作。

&lt; ----------------- new edit ----------------&gt; 好了,既然你得到了回复,你可以使用像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);
 } 

此时你应该有你的对象列表,你可以做任何你需要的事情。