使用 Microsoft Graph API 显示所有用户的文件不起作用

问题描述 投票:0回答:2

我创建了一个 .net 网站应用程序,并且添加了与下面的参考视频相同的 dll 和代码。

https://www.youtube.com/watch?v=KNJUrCHv6no&list=PLWZJrkeLOrbZ8Gl8zsxUuXTkmytyiEGSh&index=5

我已经创建了一个免费的 Microsoft 帐户,其中包含我的 ID([电子邮件受保护])的免费订阅,并且我在 azure 中注册了我的应用程序,与 https://www.youtube.com/watch?v=k7nnvdNgfOE&list=PLWZJrkeLOrbZ8Gl8zsxUuXTkmytyiEGSh&index=4此视频。

但它对我不起作用。 request.GetAsync().Result 需要更多时间并显示请求超时问题。我在下面添加了我的代码。请建议。

默认.aspx

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.Identity.Client;
using Microsoft.Graph;
using Microsoft.Extensions.Configuration;
using Helpers;
using System.Security;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        var config = LoadAppSettings();
        if (config == null)
        {
            iserror.Text = "config error";
            return;
        }
        try
        {
            var userName = ReadUsername();
            var userPassword = ReadPassword();

            var client = GetAuthenticatedGraphClient(config, userName, userPassword);

            var request = client.Me.Drive.Root.Children.Request();
            var results = request.GetAsync().Result;
            foreach (var file in results)
            {

            }
        }
        catch { iserror.Text = "config file exist. azure error"; }
    }
    private static SecureString ReadPassword()
    {
        var securePassword = "xxxxxxx";
        SecureString password = new SecureString();
        foreach (char c in securePassword)
            password.AppendChar(c);
        return password;
    }

    private static string ReadUsername()
    {
        string username;
        username = "[email protected]";
        return username;
    }
    private static GraphServiceClient GetAuthenticatedGraphClient(IConfigurationRoot config, string userName, SecureString userPassword)
    {
        var authenticationProvider = CreateAuthorizationProvider(config, userName, userPassword);
        var graphClient = new GraphServiceClient(authenticationProvider);
        return graphClient;
    }
    private static IAuthenticationProvider CreateAuthorizationProvider(IConfigurationRoot config, string userName, SecureString userPassword)
    {
        var clientId = config["applicationId"];
        var authority = "https://login.microsoftonline.com/" + config["tenantId"] + "/v2.0";

        List<string> scopes = new List<string>();
        scopes.Add("User.Read");
        scopes.Add("Files.Read");
        var cca = PublicClientApplicationBuilder.Create(clientId)
                                                .WithAuthority(authority)
                                                .Build();
        return MsalAuthenticationProvider.GetInstance(cca, scopes.ToArray(), userName, userPassword);
    }
    private static IConfigurationRoot LoadAppSettings()
    {
        try
        {
            string asas = HttpContext.Current.Server.MapPath("");
            var config = new ConfigurationBuilder()
                              .SetBasePath(asas)
                              .AddJsonFile("appsettings.json", false, true)
                              .Build();

            if (string.IsNullOrEmpty(config["applicationId"]) ||
                string.IsNullOrEmpty(config["tenantId"]))
            {
                return null;
            }

            return config;
        }
        catch (System.IO.FileNotFoundException)
        {
            return null;
        }
    }
} 

MsalAuthenticationProvider.cs

using System.Net.Http;
using System.Net.Http.Headers;
using System.Security;
using System.Threading.Tasks;
using Microsoft.Identity.Client;
using Microsoft.Graph;

namespace Helpers
{
    public class MsalAuthenticationProvider : IAuthenticationProvider
    {
        private static MsalAuthenticationProvider _singleton;
        private IPublicClientApplication _clientApplication;
        private string[] _scopes;
        private string _username;
        private SecureString _password;
        private string _userId;

        private MsalAuthenticationProvider(IPublicClientApplication clientApplication, string[] scopes, string username, SecureString password)
        {
            _clientApplication = clientApplication;
            _scopes = scopes;
            _username = username;
            _password = password;
            _userId = null;
        }

        public static MsalAuthenticationProvider GetInstance(IPublicClientApplication clientApplication, string[] scopes, string username, SecureString password)
        {
            if (_singleton == null)
            {
                _singleton = new MsalAuthenticationProvider(clientApplication, scopes, username, password);
            }

            return _singleton;
        }

        public async Task AuthenticateRequestAsync(HttpRequestMessage request)
        {
            var accessToken = await GetTokenAsync();

            request.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
        }

        public async Task<string> GetTokenAsync()
        {
            if (!string.IsNullOrEmpty(_userId))
            {
                try
                {
                    var account = await _clientApplication.GetAccountAsync(_userId);

                    if (account != null)
                    {
                        var silentResult = await _clientApplication.AcquireTokenSilent(_scopes, account).ExecuteAsync();
                        return silentResult.AccessToken;
                    }
                }
                catch (MsalUiRequiredException) { }
            }

            var result = await _clientApplication.AcquireTokenByUsernamePassword(_scopes, _username, _password).ExecuteAsync();
            _userId = result.Account.HomeAccountId.Identifier;
            return result.AccessToken;
        }
    }
}

appsettings.json*

{
  "tenantId": "xxxx",
  "applicationId": "xxxx"
}
asp.net azure-active-directory microsoft-graph-api azure-ad-graph-api office365api
2个回答
0
投票
  1. 看起来您正在运行标准
    deadlock
    异步方法尝试继续线程的情况
    blocked by the call to Result
    。尝试使用异步任务测试方法 而不是无效。

注意: 尤其是在用户交互中,应该小心阻止 通过在主线程上使用

.Result
调用,因为这种类型的调用 可以锁定您的应用程序以进行进一步的用户交互。

  1. 尝试避免在调用中使用 Result。

    var results = await request.GetAsync();
    

    然后做

    check if you need to add  async to all the methods
    .

  2. 另请检查此 c# - 使用 Microsoft 查询驱动器项目时 图 - Stack Overflow 是相关的。

  3. 此外,如果上述方法无法解决,也请尝试

    set the Timeout
    更高的价值

    示例:一小时:

    graphServiceClient.HttpProvider.OverallTimeout = TimeSpan.FromHours(1);
    

请检查以下有用的参考文献

  1. c# - 'await' 有效,但调用 task.Result 挂起/死锁 - 堆栈内存溢出 溢出
  2. 如何在控制台应用程序中访问 Microsoft Graph API (c-sharpcorner.com)

-1
投票

完成上述修复后您可以运行它吗?我也在寻找与上述解决方案相同的解决方案。但我遇到了如下不同的问题 请求正文必须包含以下参数:“client_assertion”或“client_secret”。 在这里我看到,PublicClientApplicationBuilder 类不包含 WithClientSecret 的定义。

我是不是还遗漏了什么?

我只是在寻找控制台应用程序来将文件上传到 OneDrive。

谢谢, 卡鲁纳

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.