Microsoft graph api ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier)。值不返回任何值

Microsoft graph api ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier)。值不返回任何值,microsoft-graph-api,Microsoft Graph Api,我正在创建一个mvc web应用程序,用于读取用户邮件、向用户发送邮件以及使用Microsoft Graph Api接收通知。我的应用程序已在中注册。我能够在登录和订阅通知后获取“ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).value”的返回值。但是我无法在用于侦听通知的Listen()函数中获取返回值。“对象引用未设置为对象的实例”是给定的错误。这是Listen()函数 public async Task<Ac

我正在创建一个mvc web应用程序,用于读取用户邮件、向用户发送邮件以及使用Microsoft Graph Api接收通知。我的应用程序已在中注册。我能够在登录和订阅通知后获取“ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).value”的返回值。但是我无法在用于侦听通知的Listen()函数中获取返回值。“对象引用未设置为对象的实例”是给定的错误。这是Listen()函数

public async Task<ActionResult> Listen()
    {
        // Validate the new subscription by sending the token back to Microsoft Graph.
        // This response is required for each subscription.
        if (Request.QueryString["validationToken"] != null)
        {               
            var token = Request.QueryString["validationToken"];
            return Content(token, "plain/text");
        }

        // Parse the received notifications.
        else
        {

            try
            {
                var notifications = new Dictionary<string, NotificationModel>();
                using (var inputStream = new System.IO.StreamReader(Request.InputStream))
                {
                    JObject jsonObject = JObject.Parse(inputStream.ReadToEnd());
                    if (jsonObject != null)
                    {

                        // Notifications are sent in a 'value' array. The array might contain multiple notifications for events that are
                        // registered for the same notification endpoint, and that occur within a short timespan.
                        JArray value = JArray.Parse(jsonObject["value"].ToString());
                        foreach (var notification in value)
                        {
                            NotificationModel current = JsonConvert.DeserializeObject<NotificationModel>(notification.ToString());

                            // Check client state to verify the message is from Microsoft Graph. 
                            SubscriptionStore subscription = SubscriptionStore.GetSubscriptionInfo(current.SubscriptionId);

                            // This sample only works with subscriptions that are still cached.
                            if (subscription != null)
                            {
                                if (current.ClientState == subscription.ClientState)
                                {

                                    // Just keep the latest notification for each resource.
                                    // No point pulling data more than once.
                                    notifications[current.Resource] = current;
                                }
                            }
                        }

                        if (notifications.Count > 0)
                        {

                            // Query for the changed messages. 
                         await GetChangedMessagesAsync(notifications.Values);

                        }
                    }
                }
            }
            catch (Exception)
            {
                // TODO: Handle the exception.
                // Still return a 202 so the service doesn't resend the notification.
            }

            return new HttpStatusCodeResult(202);
        }
    }

    // Get information about the changed messages and send to the browser via SignalR.
    // A production application would typically queue a background job for reliability.
    public async Task GetChangedMessagesAsync(IEnumerable<NotificationModel> notifications)
    {
        List<MessageViewModel> messages = new List<MessageViewModel>();
        MessageModel message = new MessageModel();
        string serviceRootUrl = "https://graph.microsoft.com/v1.0/";
        foreach (var notification in notifications)
        {
            SubscriptionStore subscription = SubscriptionStore.GetSubscriptionInfo(notification.SubscriptionId);
            string token;
            try
            {
                // Get the access token for the subscribed user.
                // accessToken = await GetAccessToken();
                HttpContextBase httpContext = HttpContext;
                token = await AuthHelper.GetAccessToken(httpContext);
            }
            catch (Exception e)
            {
                throw e;
            }

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, serviceRootUrl + notification.Resource);

            // Send the 'GET' request.
            GraphHttpClient graphHttpClient = new GraphHttpClient(token);
            HttpResponseMessage response = await graphHttpClient.SendAsync(request);

            // Get the messages from the JSON response.
            if (response.IsSuccessStatusCode)
            {
                string stringResult = await response.Content.ReadAsStringAsync();
                string type = notification.ResourceData.ODataType;
                if (type == "#Microsoft.Graph.Message")
                {
                    message = JsonConvert.DeserializeObject<MessageModel>(stringResult);
                    MessageViewModel messageViewModel = new MessageViewModel(message);
                    messages.Add(messageViewModel);                       
                }
            }
        }
        if (messages.Count > 0)
        {
            NotificationService notificationService = new NotificationService();
            notificationService.SendNotificationToClient(messages);  


        }



    }
公共异步任务侦听() { //通过将令牌发送回Microsoft Graph来验证新订阅。 //每个订阅都需要此响应。 if(Request.QueryString[“validationToken”!=null) { var token=Request.QueryString[“validationToken”]; 返回内容(标记,“纯/文本”); } //解析收到的通知。 其他的 { 尝试 { var notifications=newdictionary(); 使用(var inputStream=new System.IO.StreamReader(Request.inputStream)) { JObject jsonObject=JObject.Parse(inputStream.ReadToEnd()); if(jsonObject!=null) { //通知是以“值”数组发送的。该数组可能包含多个通知,用于以下事件: //为同一通知终结点注册,并在短时间内发生。 JArray value=JArray.Parse(jsonObject[“value”].ToString()); foreach(值中的var通知) { NotificationModel current=JsonConvert.DeserializeObject(notification.ToString()); //检查客户端状态以验证消息是否来自Microsoft Graph。 SubscriptionStore subscription=SubscriptionStore.GetSubscriptionInfo(current.SubscriptionId); //此示例仅适用于仍缓存的订阅。 if(订阅!=null) { if(current.ClientState==subscription.ClientState) { //只需保留每个资源的最新通知。 //多次拉取数据没有意义。 通知[current.Resource]=当前; } } } 如果(notifications.Count>0) { //查询已更改的消息。 等待GetChangedMessageAsync(notifications.Values); } } } } 捕获(例外) { //TODO:处理异常。 //仍然返回202,因此服务不会重新发送通知。 } 返回新的HttpStatusCodeResult(202); } } //获取有关更改消息的信息,并通过信号器发送到浏览器。 //生产应用程序通常会将后台作业排队以确保可靠性。 公共异步任务GetChangedMessageAsync(IEnumerable通知) { 列表消息=新列表(); MessageModel message=newmessagemodel(); 字符串serviceRootUrl=”https://graph.microsoft.com/v1.0/"; foreach(通知中的var通知) { SubscriptionStore subscription=SubscriptionStore.GetSubscriptionInfo(notification.SubscriptionId); 字符串标记; 尝试 { //获取订阅用户的访问令牌。 //accessToken=等待GetAccessToken(); HttpContextBase httpContext=httpContext; token=wait AuthHelper.GetAccessToken(httpContext); } 捕获(例外e) { 投掷e; } HttpRequestMessage请求=新的HttpRequestMessage(HttpMethod.Get,serviceRootUrl+notification.Resource); //发送“获取”请求。 GraphHttpClient GraphHttpClient=新GraphHttpClient(令牌); HttpResponseMessage response=等待图HttpClient.SendAsync(请求); //从JSON响应获取消息。 if(响应。IsSuccessStatusCode) { string stringResult=await response.Content.ReadAsStringAsync(); 字符串类型=notification.ResourceData.ODataType; if(type==“#Microsoft.Graph.Message”) { message=JsonConvert.DeserializeObject(stringResult); MessageViewModel MessageViewModel=新建MessageViewModel(消息); messages.Add(messageViewModel); } } } 如果(messages.Count>0) { NotificationService NotificationService=新建NotificationService(); notificationService.SendNotificationToClient(消息); } } 这是GetAccessToken()方法,其中使用了“ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value”

公共静态异步任务GetAccessToken(HttpContextBase HttpContext) { string accessToken=string.Empty; //从web.config加载应用程序配置 字符串appId=ConfigurationManager.AppSettings[“ida:appId”]; 字符串appPassword=ConfigurationManager.AppSettings[“ida:appPassword”];
public static async Task<string> GetAccessToken(HttpContextBase HttpContext)
    {
        string accessToken = string.Empty; ;
        // Load the app config from web.config
        string appId = ConfigurationManager.AppSettings["ida:AppId"];
        string appPassword = ConfigurationManager.AppSettings["ida:AppPassword"];
        string redirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"];
        string[] scopes = ConfigurationManager.AppSettings["ida:AppScopes"]
            .Replace(' ', ',').Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

        string userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;

            if (!string.IsNullOrEmpty(userId))
            {
                // Get the user's token cache
                SessionTokenCache tokenCache = new SessionTokenCache(userId, HttpContext);

                ConfidentialClientApplication cca = new ConfidentialClientApplication(
                    appId, redirectUri, new Microsoft.Identity.Client.ClientCredential(appPassword), tokenCache.GetMsalCacheInstance(), null);


                // Call AcquireTokenSilentAsync, which will return the cached
                // access token if it has not expired. If it has expired, it will
                // handle using the refresh token to get a new one.
                AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes, cca.Users.FirstOrDefault());

                accessToken = result.AccessToken;
            }

        // Get the current user's ID           

        return accessToken;
    }