简体   繁体   English

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

[英]Consuming WEB API using HttpClient in c# console application

I have created a web API in visual studio 2015 using a MySQL database.我使用 MySQL 数据库在 Visual Studio 2015 中创建了一个 Web API。 The API is working perfect. API 运行良好。

So I decided to make a console client application in which I can consume my web-service (web API).所以我决定制作一个控制台客户端应用程序,我可以在其中使用我的网络服务(网络 API)。 The client code is based on HttpClient , and in the API I have used HttpResponse .客户端代码基于HttpClient ,在 API 中我使用了HttpResponse Now when I run my console application code, I get nothing.现在,当我运行我的控制台应用程序代码时,我什么也得不到。 Below is my code:下面是我的代码:

Class班级

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

This class is same as in my web API model class:这个类与我的 Web API 模型类相同:

Model in 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; }
}

Console application code控制台应用程序代码

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

In my API I have 3 GET methods under a single controller, so I have created different routes for them.在我的 API 中,我在单个控制器下有 3 个GET方法,因此我为它们创建了不同的路由。 Also the URL for them is different.它们的 URL 也不同。

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

While debugging the code, I found that List<meters_info_dev> mID = new List<meters_info_dev>();在调试代码时,发现List<meters_info_dev> mID = new List<meters_info_dev>(); is empty:是空的:

在此处输入图片说明

While the response is 302 Found , the URL is also correct:虽然响应是302 Found ,但 URL 也是正确的:

在此处输入图片说明

Update 1更新 1

After a suggestion I have done the following:在提出建议后,我做了以下工作:

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;
}

When I run the application, I get the exception "An invalid request URI was provided. The request URI must either be an absolute URI or BaseAddress must be set."当我运行应用程序时,我收到异常“提供了无效的请求 URI。请求 URI 必须是绝对 URI 或必须设置BaseAddress 。”

Update 2更新 2

I have added a new piece of code:我添加了一段新代码:

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

And in the response I am getting all the records:在响应中,我得到了所有记录:

在此处输入图片说明

I don't know why it's not working with the other logic and what the problem is.我不知道为什么它不能与其他逻辑一起使用以及问题是什么。 I have also read the questions Httpclient consume web api via console app C# and Consuming Api in Console Application .我还阅读了Httpclient 通过控制台应用程序 C#Consuming Api in Console Application 使用 web api的问题。

Any help would be highly appreciated.任何帮助将不胜感激。

The code needs quite a bit of work.代码需要相当多的工作。

The line you highlighted will always be empty because that's where you initialise the variable.您突出显示的行将始终为空,因为这是您初始化变量的地方。 What you want is run thorugh the code until you get the result back form the call.你想要的是通过代码运行,直到你从调用中得到结果。

First, make sure your api actually works, you can call the GET method you want in the browser and you see results.首先,确保您的 api 确实有效,您可以在浏览器中调用您想要的 GET 方法并看到结果。

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

that's an example of course, so replace that with your particular data and methods.这当然是一个例子,所以用你的特定数据和方法替换它。

now, when you check the results just because your response.IsSuccessStatusCode is false that doesn't mean there are no records.现在,当您仅仅因为您的 response.IsSuccessStatusCode 为 false 而检查结果时,并不意味着没有记录。 What it means is that the call failed completely.这意味着呼叫完全失败。 Success result with an empty list is not the same thing as complete failure.带有空列表的成功结果与完全失败不同。

If you want to see what you get back you can alter your code a little bit:如果你想看看你得到了什么,你可以稍微改变你的代码:

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

put a breakpoint on this line and see what you actually get back, then you worry about casting the result to your list of objects.在这一行上放置一个断点,看看你实际得到了什么,然后你担心将结果投射到你的对象列表中。 Just make sure you get back the same thing you get when you test the call in the browser.只要确保您返回与在浏览器中测试调用时得到的相同内容即可。

<-------------------------------> More details after edit. <-------------------------------> 编辑后的更多细节。

Why don't you simplify your code a little bit.为什么不稍微简化一下代码。

for example just set the URL of the request in one go :例如,只需一次性设置请求的 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
            }

Your first order of the day is to see if you can hit the url and get the data.您一天中的第一个任务是查看您是否可以点击 url 并获取数据。 You can worry about the base address once you get a correct response.一旦得到正确的响应,您就可以担心基地址。 Start simple and work your way up from there, once you have a working sample.一旦你有了一个工作样本,从简单开始,然后从那里开始。

<----------------- new edit ----------------> Ok, now that you are getting a response back, you can serialise the string back to the list of objects using something like Newtonsoft.Json. <----------------- 新编辑 ----------------> 好的,现在你得到了回复,你可以使用 Newtonsoft.Json 之类的东西将字符串序列化回对象列表。 This is a NuGet package, you might either have it already installed, if not just add it.这是一个 NuGet 包,您可能已经安装了它,如果没有添加它。

Add a using statement at the top of the file.在文件顶部添加 using 语句。

using Newtonsoft.Json;

then your code becomes something like :那么你的代码就会变成这样:

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

At this point you should have your list of objects and you can do whatever else you need.在这一点上,你应该有你的对象列表,你可以做任何你需要的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM