如何从Windows服务调用REST API

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何从Windows服务调用REST API相关的知识,希望对你有一定的参考价值。

我试图从Windows服务调用Rest API。我以前从未尝试过这个。我不知道为什么我无法拨打这个电话。

我的代码:

    string urlParameter = "posts/1";
    var client = new HttpClient();
    client.BaseAddress = new Uri("http://jsonplaceholder.typicode.com/");
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    HttpResponseMessage response = client.GetAsync(urlParameter).Result;
    if (response.IsSuccessStatusCode)
    {
        var dataObj = response.Content.ReadAsAsync<IEnumerable<MyType>>().Result;
    }

我收到以下错误:

  • 消息:发送请求时发生错误。
  • 内部异常消息:{“底层连接已关闭:连接意外关闭。”}
  • System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)中的内部异常堆栈跟踪 在System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)

在以下行生成此错误:

HttpResponseMessage response = client.GetAsync(urlParameter).Result;

任何建议,将不胜感激。

编辑:(更新的代码)

    string urlParameter = "posts/1";
    var client = new HttpClient();
    client.BaseAddress = new Uri("http://jsonplaceholder.typicode.com/");
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    try
    {
        //var response = await client.GetAsync(urlParameter);
        var task = client.GetAsync(urlParameter);
        task.Wait();
        var response = task.Result;

        if (response.IsSuccessStatusCode)
        {
            var dataObj = response.Content.ReadAsAsync<IEnumerable<MyType>>().Result;
        }
    }
    catch (Exception ex)
    {
        string a = ex.Message;
        string b = ex.ToString();
    }

编辑2 :(仍然得到相同的错误)

private static async void TestAPI2()
{
    using (HttpClient client = new HttpClient())
    {
        client.DefaultRequestHeaders.Add("Get", "application/json");

        var response = await client.GetAsync("http://jsonplaceholder.typicode.com/posts/1");

        string context = await response.Content.ReadAsStringAsync();

    }
}
答案

你的问题是......

var response = client.GetAsync(urlParameter);

...返回一个任务,你需要等待它先完成。

打这个电话最干净的方式就是这样......

var response = await client.GetAsync(urlParameter);

...这需要代码在这样的异步方法中运行......

public async Task Foo() 
{
   var response = await client.GetAsync(urlParameter);
}

...或者您可以简单地告诉编译器等待...

var task = client.GetAsync(urlParameter);
task.Wait();

var response = task.Result;

......或者更紧凑的版本可能会使用这样的延续......

var result = await client.GetAsync(urlParameter)
    .ContinueWith(t => t.Result.Content.ReadAsAsync<IEnumerable<MyType>>())
    .Unwrap();

...这将执行请求,然后当请求返回时异步解析它并解开任务返回“内部结果”,因为此代码创建一个任务>>你只需要IEnumerable所以等待解包的任务得到你一个接一个地执行2个任务的结果:)

...我查看了您的特定代码并在新的控制台应用程序中运行,请将其更新为此...

 class MyType
        {
          public int userId { get; set; }
          public int id { get; set; }
          public string title { get; set; }
          public string body { get; set; }
        }

        static void TestAnApiCall()
        {
            string urlParameter = "posts/1";
            var client = new HttpClient();
            client.BaseAddress = new Uri("http://jsonplaceholder.typicode.com/");
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            try
            {
                //var response = await client.GetAsync(urlParameter);
                var task = client.GetAsync(urlParameter);
                task.Wait();
                var response = task.Result;

                if (response.IsSuccessStatusCode)
                {
                    var readTask = response.Content.ReadAsAsync<MyType>();
                    readTask.Wait();
                    var dataObj = readTask.Result;
                    Console.WriteLine(JsonConvert.SerializeObject(dataObj));
                }
            }
            catch (Exception ex)
            {
                string a = ex.Message;
                string b = ex.ToString();
            }
        }
另一答案

是的,它确实在“控制台应用程序”中工作,但是相同的代码在窗口服务中不起作用。 - John Doe

想对此评论作出回复。我确实面临过类似的问题。 Rest API无法从Windows服务调用,但它可以从控制台应用程序中运行。显示为

{System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 80.228.241.59:443
   at System.Net.Sockets.Socket.InternalEndConnect(IAsyncResult asyncResult)
   at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult)
   at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception)
   --- End of inner exception stack trace ---

由于防火墙问题,这一切都发生在我身上。最后能够使用RestClient中的代理设置来解决这个问题并且它有效。

以上是关于如何从Windows服务调用REST API的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Angular 7 的激活链接中获取 url 参数并从服务类调用 rest api

如何在微服务中处理从 UI 到 API 的 REST 调用

如何列出对服务器进行的 REST API 调用 [重复]

如何从远程机器访问 REST API?

来自 wordpress 的 REST API 调用中的服务不可用

从 ASP.net 4 Web API 2 项目通过 HttpClient 调用 REST 服务导致异常