【问题标题】:Specify Localhost Port for C# .NET Async / Await Requests in Visual Studio在 Visual Studio 中为 C# .NET 异步/等待请求指定 localhost 端口
【发布时间】:2017-05-08 14:46:43
【问题描述】:

我正在调试一个使用 Oauth2 凭据的控制台应用程序,并且服务提供商要求我指定一个重定向 URI。我在服务提供商的 Web 门户中指定重定向 URI。该服务是谷歌分析。

我已使用 Node.js 应用程序成功测试了该服务。在服务的配置中,我指定了http://localhost:8080 的重定向URI。 Node 应用程序实际上默认在 8080 端口启动,所以我可以简单地运行 http-server,浏览到 http://localhost:8080,调用服务,然后查看带有数据的响应。

但是,当我尝试使用 C# 控制台应用程序调用相同的服务时,我在浏览器中收到 HTTP 400 错误。错误状态:

The redirect URI in the request, http://localhost:59291/authorize/, does not match the ones authorized for the OAuth client.

每次我尝试运行应用程序时,端口都会发生变化。下面是代码(引用自Analytics Reporting API V4 Client Library for .NET):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Google.Apis.AnalyticsReporting.v4;
using Google.Apis.AnalyticsReporting.v4.Data;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using System.Threading;

namespace Google_Analytics_API_Test
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var credential = GetCredential().Result;
                using (var svc = new AnalyticsReportingService(
                    new BaseClientService.Initializer
                    {
                        HttpClientInitializer = credential,
                        ApplicationName = "Google Analytics API Console"
                    }))
                {
                    var dateRange = new DateRange
                    {
                        StartDate = "2017-04-24",
                        EndDate = "today"
                    };
                    var sessions = new Metric
                    {
                        Expression = "ga:sessions",
                        Alias = "Sessions"
                    };
                    var date = new Dimension { Name = "ga:date" };

                    var reportRequest = new ReportRequest
                    {
                        DateRanges = new List<DateRange> { dateRange },
                        Dimensions = new List<Dimension> { date },
                        Metrics = new List<Metric> { sessions },
                        ViewId = "<<viewID>>"
                    };

                    var getReportsRequest = new GetReportsRequest
                    {
                        ReportRequests = new List<ReportRequest> {    reportRequest }
                    };
                    var batchRequest =    svc.Reports.BatchGet(getReportsRequest);
                    var response = batchRequest.Execute();
                    foreach (var x in response.Reports.First().Data.Rows)
                    {
                        Console.WriteLine(string.Join(",", x.Dimensions) +
                            " " + string.Join(", ",    x.Metrics.First().Values));
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

            static async Task<UserCredential> GetCredential()
            {
                using (var stream = new FileStream("client_secret.json",
                    FileMode.Open, FileAccess.Read))
                {
                    const string loginEmailAddress = "<<emailAddress>>";
                return await GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    new[] { AnalyticsReportingService.Scope.Analytics },
                    loginEmailAddress, CancellationToken.None,
                    new FileDataStore("GoogleAnalyticsApiConsole"));
                }
           }
       }
    }

我已经搜索了一种使用静态端口配置 IIS Express 以进行调试的方法,但我不确定这里是否涉及 IIS - 而不仅仅是由 Google Analytics 库实现的 TcpClient / TcpListener 对象之类的东西?

有没有办法在 C# .NET 控制台应用程序中为异步/等待请求指定端口?

【问题讨论】:

  • 您是否遵循了所有的配置步骤,包括生成和设置json文件? OAuth 回调适用于网站应用程序,而不是回调。这是 OAuth 提供者告诉您的“网站”I just authenticated a user with this token, let him pass 的方式。显然这对于​​桌面客户端应用程序来说毫无意义。
  • 您链接到的答案显然有效,没有导致回调。创建一个新项目并按照该答案中描述的步骤操作,确保完成所有配置步骤,将所有常量设置为正确的值,将正确的设置写入 json 文件等

标签: c# .net visual-studio async-await google-api-dotnet-client


【解决方案1】:

显然,这里的问题是您的请求是通过 HttpClient 发出的; Google.Apis.Http.HttpClientfactory 通过 ConfigurableHttpClient 返回它。 HttpClient 不会将方法暴露给底层的 ServicePoint 来设置本地绑定的 IP 地址(更多信息在底部)

解决此问题的最佳方法是确保您以正确的方式使用凭据。由于您是从控制台应用程序连接的,因此您可以轻松地将这些凭据设置为“其他”,这实际上是首选方式。尝试查看“创建凭据”按钮并选择“帮助我选择”,它可以引导您完成场景。否则,只需创建如下。

根据@panagiotis-kanavos 的建议,我将添加说明:

HttpClient 不公开对 ServicePoint 的访问。你可以使用反射 访问底层的 ServicePoint 对象。它可能会提供一个解决方案 如果您不想尝试绑定到特定的本地地址 将控制台 API 凭据与 Google API for Analytics 一起使用

为此,请检查以下问题:Use httpclient to send a request from a specific IP address

据我所知,BaseClientService 只允许您设置自定义 HttpFactory 或自定义 HttpClientInitializer(修改后创建),因此您需要创建一个自定义 HttpFactory 实例,返回如上所述修改的 ConfigurableHttpClient。

  1. GoogleApi HttpClientFactory
  2. GoogleApi ConfigurableHttpClient

完成后,您将通过自定义 HttpClientFactory。

 using (var svc = new AnalyticsReportingService(
     new BaseClientService.Initializer
 {
     HttpClientInitializer = credential,
     ApplicationName = "Google Analytics API Console",
     HttpClientFactory = new CustomHttpClientFactory()
 }))

【讨论】:

  • 我不确定这是否有意义。 HttpClient 使用 HttpWebRequest。 IPEndpoint 只是一个地址,它不是一个监听器。即使您确实创建了一个 HttpListener,您也将无法接收调用,因为任何(如果不是全部)中间路由器都会阻止对该端口的访问。如果你想创建一个 HttpListener 无论如何你如何发出出站请求都没有关系
  • WebRequest 使用 ServicePoint 管理器,因此您实际上可以绑定到 IPEndpoint,因为这在他的情况下甚至是不可能的,我不确定为什么需要额外说明,但我已经添加了它。
  • 和使用 WebRequest 的 HttpClient 也是如此。 IPEndpoint 只是 *address 它不绑定到任何东西,不听任何东西。 监听的是HttpListener
  • 可以,但是HttpClient不暴露ServicePoint;您可以使用反射来访问 HttpWebRequest 的 ServicePoint 方法;但是,当他可以简单地纠正他对凭据的使用时,这将如何提供答案?如果他将 API Oauth 凭据设置为接受来自他的控制台客户端的调用,他就不用担心了。
  • @Kaylus 感谢您提供附加信息和清晰的解释,帮助我了解 .NET 控制台应用程序中发生的情况。您提供的解决方案很有趣,它确实说明了我的初始方法的复杂性与遵循您的原始指导更改 Google Analytics(分析)中的凭证类型的简单性。使用另一个凭据是解决我的问题的最佳方法(在各个方面),但我现在确实更好地理解了 async / await 请求的情况,非常感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-05
  • 1970-01-01
  • 1970-01-01
  • 2021-05-17
  • 2013-03-27
  • 1970-01-01
相关资源
最近更新 更多