Добавление событий календаря Outlook 365 без многократного входа в систему C # - PullRequest
0 голосов
/ 05 октября 2018

Это продолжение предыдущего вопроса: Как добавить события календаря в Outlook 365 с помощью C # MSGraph Спасибо пользователю Seiya Su за помощь.

Я пытаюсь использовать Microsoft.Graph в приложении Windows Form для Visual Studio C #, чтобы добавить некоторые дополнительные функции в Outlook 365. Это мое первое приложение, созданное с помощью Microsoft.Graph, и у меня былоТрудно найти документацию для его интеграции с C #, поэтому, пожалуйста, прости меня за отсутствие знаний.

В основном, я хочу иметь возможность добавить несколько предустановленных событий календаря, детали которых встроены в форму Windows, оптом из одногоНажатие кнопки, проблема, с которой я сталкиваюсь, заключается в том, что всякий раз, когда я вызываю мой метод SetAppointment () или graphTesting (), я должен войти в систему для каждого выполненного действия.Когда я пытаюсь добавить более 60 событий в календарь, повторный вход в систему каждый раз, когда мы хотим добавить одно событие, недопустим.У кого-нибудь есть идеи, как этого добиться?Я согласен с тем, что пользователю необходимо войти в систему, если он должен сделать это только в начале выполнения программы.

using Microsoft.Graph;
using Microsoft.Identity.Client;
using System.Configuration;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections.Generic;

namespace WindowsFormsApp
{
    class MSGraph
    {
        PublicClientApplication clientApp;
        GraphServiceClient graphClient;

        public async void Start()
        {
            await GetDataAsync();
            return;
        }

        // Starts the login process
        async Task GetDataAsync()
        {
            clientApp = new PublicClientApplication(ConfigurationManager.AppSettings["ClientId"].ToString());

            graphClient = new GraphServiceClient(
                    "https://graph.microsoft.com/v1.0",
                    new DelegateAuthenticationProvider(
                        async (requestMessage) =>
                        {
                            requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", await GetTokenAsync(clientApp));
                        }));

            userEmail = currentUser.ToString();
            return;
    }


    // Fetches Access Token
    async Task<string> GetTokenAsync(PublicClientApplication clientApp)
    {
        //need to pass scope of activity to get token
        string[] Scopes = { "User.ReadWrite.All", "Calendars.ReadWrite", "Calendars.ReadWrite.Shared" };
        token = null;

        AuthenticationResult authResult = await clientApp.AcquireTokenAsync(Scopes).ConfigureAwait(false);
        token = authResult.AccessToken;

        return token;
    }

    // Testing out MSGraph
    public async void graphTesting()
            { 
        var myEvent = new Microsoft.Graph.Event();
        myEvent.Subject = "Test";
        myEvent.Body = new ItemBody() { ContentType = BodyType.Text, Content = "This is test." };
        myEvent.Start = new DateTimeTimeZone() { DateTime = "2018-10-3T12:00:00", TimeZone = "Pacific Standard Time" };
        myEvent.End = new DateTimeTimeZone() { DateTime = "2018-10-3T13:00:00", TimeZone = "Pacific Standard Time" };
        myEvent.Location = new Location() { DisplayName = "conf room 1" };



        var myEvent2 = new Microsoft.Graph.Event();
        myEvent2.Subject = "Test";
        myEvent2.Body = new ItemBody() { ContentType = BodyType.Text, Content = "This is test." };
        myEvent2.Start = new DateTimeTimeZone() { DateTime = "2018-10-4T12:00:00", TimeZone = "Pacific Standard Time" };
        myEvent2.End = new DateTimeTimeZone() { DateTime = "2018-10-4T13:00:00", TimeZone = "Pacific Standard Time" };
        myEvent2.Location = new Location() { DisplayName = "conf room 1" };    


        // Create the event.
        var user = graphClient.Users["myEmail"].Calendar.Events.Request();
        await user.AddAsync(myEvent);
        await user.AddAsync(myEvent2);


    }



    // Adds Events to the Calendar
    public async void SetAppointment(string Subject, string Body, string Start, string End, string Location, List<string> attendees) 
    {
        var myEvent = new Microsoft.Graph.Event();
        myEvent.Subject = Subject;
        myEvent.Body = new ItemBody() { ContentType = BodyType.Text, Content = Body };
        myEvent.Start = new DateTimeTimeZone() { DateTime = Start, TimeZone = "" };
        myEvent.End = new DateTimeTimeZone() { DateTime = End, TimeZone = "" };
        myEvent.Location = new Location() { DisplayName = Location };

        var appointment = await graphClient.Me.Calendar.Events.Request().AddAsync(myEvent);          

    }

}

}

1 Ответ

0 голосов
/ 07 октября 2018

Где вы регистрируете свое приложение: приложение Azure или приложение MSAL ?В большинстве случаев мы можем использовать метод AcquireTokenSilentAsync из Microsoft.Identity.Client , но не AcquireTokenAsync из Microsoft.Identity.Client.ActiveDirectory чтобы получить токен.

Причиной является проблема в вашем коде, у вас нет кэша токена .Таким образом, вы запрашиваете новый токен для каждого запроса (войдите снова) start начните с График Официальные документы , чтобы узнать, как кэшировать токен, поскольку вы используете WinForm, так что вы можете ссылаться на демонстрацию UWP (я создалпроект WinForm и добавьте мой код ниже).Вы можете реализовать логику TokenCache, следуя MVC код начала работы .

Для тестирования вы можете просто использовать следующий код из моего: Создайте класс и присвойте ему имя AuthenticationHelper :

   public class AuthenticationHelper
    {
        // The Client ID is used by the application to uniquely identify itself to the v2.0 authentication endpoint.
        static string clientId = ConfigurationManager.AppSettings["AppId"].ToString();
        public static string[] Scopes = { "Calendars.ReadWrite", "User.Read", "Mail.Send", "Files.ReadWrite" };        

        public static PublicClientApplication IdentityClientApp = new PublicClientApplication(clientId);

        public static string TokenForUser = null;
        public static DateTimeOffset Expiration;

        private static GraphServiceClient graphClient = null;      

        // Get an access token for the given context and resourceId. An attempt is first made to 
        // acquire the token silently. If that fails, then we try to acquire the token by prompting the user.
        public static GraphServiceClient GetAuthenticatedClient()
        {
            if (graphClient == null)
            {
                // Create Microsoft Graph client.
                try
                {
                    graphClient = new GraphServiceClient(
                        "https://graph.microsoft.com/v1.0",
                        new DelegateAuthenticationProvider(
                            async (requestMessage) =>
                            {
                                var token = await GetTokenForUserAsync();
                                requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", token);
                                // This header has been added to identify our sample in the Microsoft Graph service.  If extracting this code for your project please remove.
                                //requestMessage.Headers.Add("SampleID", "uwp-csharp-connect-sample");

                            }));
                    return graphClient;
                }

                catch (Exception ex)
                {
                    Debug.WriteLine("Could not create a graph client: " + ex.Message);
                }
            }

            return graphClient;
        }


        /// <summary>
        /// Get Token for User.
        /// </summary>
        /// <returns>Token for user.</returns>
        public static async Task<string> GetTokenForUserAsync()
        {
            AuthenticationResult authResult;
            try
            {
                //need to pass scope of activity to get token
                if (TokenForUser == null)
                {
                    authResult = await IdentityClientApp.AcquireTokenSilentAsync(Scopes, IdentityClientApp.Users.First());
                    TokenForUser = authResult.AccessToken;
                }
                return TokenForUser;
            }

            catch (Exception ex)
            {
                if (TokenForUser == null || Expiration <= DateTimeOffset.UtcNow.AddMinutes(5))
                {
                    authResult = await IdentityClientApp.AcquireTokenAsync(Scopes);

                    TokenForUser = authResult.AccessToken;
                    Expiration = authResult.ExpiresOn;
                }
            }

            return TokenForUser;
        }
        /// <summary>
        /// Signs the user out of the service.
        /// </summary>
        public static void SignOut()
        {
            foreach (var user in IdentityClientApp.Users)
            {
                IdentityClientApp.Remove(user);
            }
            graphClient = null;
            TokenForUser = null;

        }

    }

В форме .CS класс:

public partial class Form1 : Form
    { 
        public Form1()
        {
            InitializeComponent(); 
        }

        /// <summary>
        /// Register event button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            graphTesting();
        } 

        // Testing out MSGraph
        public async void graphTesting()
        { 
            // Initialize the GraphServiceClient.
            // GraphServiceClient graphClient = Microsoft_Graph_SDK_ASPNET_Connect.Helpers.SDKHelper.GetAuthenticatedClient();
            var graphClient = AuthenticationHelper.GetAuthenticatedClient();

            var myEvent = new Microsoft.Graph.Event();
            myEvent.Subject = "Test";
            myEvent.Body = new ItemBody() { ContentType = BodyType.Text, Content = "This is test." };
            myEvent.Start = new DateTimeTimeZone() { DateTime = "2018-10-3T12:00:00", TimeZone = "Pacific Standard Time" };
            myEvent.End = new DateTimeTimeZone() { DateTime = "2018-10-3T13:00:00", TimeZone = "Pacific Standard Time" };
            myEvent.Location = new Location() { DisplayName = "conf room 1" };

            var myEvent2 = new Microsoft.Graph.Event();
            myEvent2.Subject = "Test";
            myEvent2.Body = new ItemBody() { ContentType = BodyType.Text, Content = "This is test." };
            myEvent2.Start = new DateTimeTimeZone() { DateTime = "2018-10-4T12:00:00", TimeZone = "Pacific Standard Time" };
            myEvent2.End = new DateTimeTimeZone() { DateTime = "2018-10-4T13:00:00", TimeZone = "Pacific Standard Time" };
            myEvent2.Location = new Location() { DisplayName = "conf room 1" };


            // Create the event.
            //var user = graphClient.Users["test@test.onmicrosoft.com"].Calendar.Events.Request();
            await graphClient.Users["test@test.onmicrosoft.com"].Calendar.Events.Request().AddAsync(myEvent);
            await graphClient.Users["test@test.onmicrosoft.com"].Calendar.Events.Request().AddAsync(myEvent2);
            await graphClient.Users["test@test.onmicrosoft.com"].Calendar.Events.Request().AddAsync(myEvent);
            await graphClient.Users["test@test.onmicrosoft.com"].Calendar.Events.Request().AddAsync(myEvent2);

        }



        /// <summary>
        /// Sign in button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void button2_Click(object sender, EventArgs e)
        { 
            if (await SignInCurrentUserAsync())
            {

            }           
        }

        public async Task<bool> SignInCurrentUserAsync()
        {
            try
            {
                var graphClient = AuthenticationHelper.GetAuthenticatedClient();

                if (graphClient != null)
                {
                    var user = await graphClient.Me.Request().GetAsync();
                    string userId = user.Id;

                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Microsoft.Identity.Client.MsalException)
            {
                return false;
            }


        }

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...