简体   繁体   中英

How To Add Calendar Events to Outlook 365 Using C# MSGraph

A current application I'm working on is to create essentially a wrapper application for Microsoft Outlook 365. I haven't worked much with MSGraph, and have been having a hard time setting events to the logged in user's calendar from the Form Window, or really doing anything after acquiring a token. and this is the code I'm currently trying to use.

    PublicClientApplication clientApp;
    GraphServiceClient graphClient;
    string token;
    string userEmail;


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

    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));
                        }));

        var currentUser = await graphClient.Me.Request().GetAsync().ConfigureAwait(false);
        userEmail = currentUser.Mail;
        return;
    }


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

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

        return token;
    }


    public async void SetAppointment(string subject, DateTime start, DateTime end, List<Attendee> attendies)
    {
        try
        {
            using (HttpClient c = new HttpClient())
            {
                String requestURI = "https://graph.microsoft.com/v1.0/users/" + userEmail + "/calendar/events.";


                ToOutlookCalendar toOutlookCalendar = new ToOutlookCalendar();


                TimeZone Timezone = TimeZone.CurrentTimeZone;
                toOutlookCalendar.Subject = subject;
                toOutlookCalendar.Start = start;
                toOutlookCalendar.End = end;
                toOutlookCalendar.Attendees = attendies;


                HttpContent httpContent = new StringContent(JsonConvert.SerializeObject(toOutlookCalendar), Encoding.UTF8, "application/json");

                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestURI);
                request.Content = httpContent;
                //Authentication token
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);

                var response = await c.SendAsync(request);
                var responseString = await response.Content.ReadAsStringAsync();
            }
        }
        catch (Exception e)
        {
            MessageBox.Show(e.Message);
        }
    }

UPDATE

Okay thanks to Seiya Su below I managed to make this code work for the most part, However, every single time I add an event to the calendar it requires logging in.

    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);          

I built a test method to mess around and tried things like this:

    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" };
        //myEvent.Attendees = attendies;                   


        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" };
        //myEvent.Attendees = attendies;                   



        // Create the event.
        var user = graphClient.Me.Calendar.Events.Request();
        await user.Header("bearer", token).AddAsync(myEvent);
        await user.Header("bearer", token).AddAsync(myEvent2);

    }

But it still didn't work and asked me to log in for every event added. I am OKAY with the user having to log in, as long as they only log in once, does anyone know a way around this issue? My current thought was to pass the token along to the request but that seemed to do nothing.

1 You use wrong EndPoint in your code.

2 Since you can use the MS Graph Library, here's a more efficient worked code.You can just re-encapsulate it.

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-9-29T12:00:00", TimeZone = "Pacific Standard Time" };
myEvent.End = new DateTimeTimeZone() { DateTime = "2018-9-29T13:00:00", TimeZone = "Pacific Standard Time" };
myEvent.Location = new Location() { DisplayName = "conf room 1" }; 
 //myEvent.Attendees = attendies;                   

 // Create the event. 
 //graphClient.Me.Calendar.Events.Request().AddAsync(myEvent)
 var mySyncdEvent = await graphClient.Users["you mail"].Calendar.Events.Request()
.AddAsync(myEvent);

Update 2018-10-5

For your updated code, we don't need to pass the token everytime. I am not sure your From Windows is WPF or Winform or such.The code and auth flow should work better for MVC project. Just try to pass offline or such Scope to your GraphScope setting file.

Last. Don't always update the new issue you encounter to the exist question. Although they are related, but not one question any more. While the old question have close, the better open a new one. Otherwise they are still one issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM