在C#控制台应用程序中使用HttpClient消耗WEB API [英] Consuming WEB API using HttpClient in c# console application

查看:63
本文介绍了在C#控制台应用程序中使用HttpClient消耗WEB API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在Visual Studio 2015中使用MySQL数据库创建了一个Web API.该API工作正常.

I have created a web API in visual studio 2015 using a MySQL database. The API is working perfect.

因此,我决定制作一个控制台

So I decided to make a console client application in which I can consume my web-service (web API). The client code is based on HttpClient, and in the API I have used HttpResponse. Now when I run my console application code, I get nothing. Below is my code:

课程

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

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

This class is same as in my web API model class:

网络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也不同.

In my API I have 3 GET methods under a single controller, so I have created different routes for them. Also the URL for them is different.

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

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

While debugging the code, I found that List<meters_info_dev> mID = new List<meters_info_dev>(); is empty:

响应为302 Found时,URL也正确:

While the response is 302 Found, the URL is also correct:

提出建议后,我做了以下事情:

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

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

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."

我添加了一段新代码:

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:

我不知道为什么它不能与其他逻辑一起工作以及问题出在哪里.我还阅读了 Httpclient通过控制台应用程序C#消耗Web api的问题在控制台应用程序中使用Api .

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.

任何帮助将不胜感激.

推荐答案

代码需要大量工作.

突出显示的行将始终为空,因为这是初始化变量的地方.您想要的是通过代码运行,直到您从调用返回结果为止.

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.

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

First, make sure your api actually works, you can call the GET method you want in the browser and you see results.

 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.

现在,当您仅因为您的response.IsSuccessStatusCode为false时就检查结果时,这并不意味着没有记录.这意味着呼叫完全失败.空列表的成功结果与完全失败不是同一回事.

now, when you check the results just because your response.IsSuccessStatusCode is false that doesn't mean there are no records. 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.

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

for example just set the URL of the request in one go :

 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. 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.

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

<----------------- 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. This is a NuGet package, you might either have it already installed, if not just add it.

在文件顶部添加using语句.

Add a using statement at the top of the file.

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

这时,您应该拥有对象列表,您可以做任何您需要的其他事情.

At this point you should have your list of objects and you can do whatever else you need.

这篇关于在C#控制台应用程序中使用HttpClient消耗WEB API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆