Beispiel #1
0
        public async Task <string> SaveAttachmentOneDrive([FromBody] SaveAttachmentRequest request)
        {
            if (request == null || !request.IsValid() || request.attachmentIds.Length == 0)
            {
                return(null);
            }

            string attachmentsUrl = null;

            using (var client = new HttpClient())
            {
                // Get content bytes
                string baseAttachmentUri = request.outlookRestUrl;
                if (!baseAttachmentUri.EndsWith("/"))
                {
                    baseAttachmentUri += "/";
                }
                baseAttachmentUri += "v2.0/me/messages/" + request.messageId + "/attachments/";

                var i = 0;
                foreach (string attachmentId in request.attachmentIds)
                {
                    var getAttachmentReq = new HttpRequestMessage(HttpMethod.Get, baseAttachmentUri + attachmentId);

                    // Headers
                    getAttachmentReq.Headers.Authorization = new AuthenticationHeaderValue("Bearer", request.outlookToken);
                    getAttachmentReq.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                    var result = await client.SendAsync(getAttachmentReq);

                    string json = await result.Content.ReadAsStringAsync();

                    OutlookAttachment attachment = JsonConvert.DeserializeObject <OutlookAttachment>(json);

                    // For files, build a stream directly from ContentBytes
                    if (attachment.Size < (4 * 1024 * 1024))
                    {
                        MemoryStream fileStream = new MemoryStream(Convert.FromBase64String(attachment.ContentBytes));


                        // Get access token from SQL database
                        var token = Data.GetUserSessionToken(Settings.GetUserAuthStateId(ControllerContext.HttpContext), Settings.AzureADAuthority);

                        // TODO: Check if the file already exists

                        attachmentsUrl = await GraphApiHelper.saveAttachmentOneDrive(token.AccessToken, Format.MakeFileNameValid(request.filenames[i]), fileStream, Format.MakeFileNameValid(request.subject));

                        // Format
                        string delete = "/" + request.filenames[i];
                        attachmentsUrl = attachmentsUrl.Replace(delete, "");

                        i++;
                    }
                    else
                    {
                        // Functionality to support > 4 MB files
                        // See https://docs.microsoft.com/en-us/graph/api/driveitem-createuploadsession?view=graph-rest-1.0
                        var token = Data.GetUserSessionToken(Settings.GetUserAuthStateId(ControllerContext.HttpContext), Settings.AzureADAuthority);

                        DriveItem folder = await GraphApiHelper.searchFileOneDrive(token.AccessToken, "Outlook Attachments");


                        var url       = "https://graph.microsoft.com/v1.0" + $"/me/drive/items/{folder.Id}:/{attachment.Name}:/createUploadSession";
                        var uploadReq = new HttpRequestMessage(HttpMethod.Post, url);


                        // Headers
                        uploadReq.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);

                        // Send request
                        var sessionResponse = client.SendAsync(uploadReq).Result.Content.ReadAsStringAsync().Result;


                        var uploadSession = JsonConvert.DeserializeObject <UploadSessionResponse>(sessionResponse);

                        Upload upload = new Upload();

                        HttpResponseMessage response = upload.UploadFileBySession(uploadSession.uploadUrl, Convert.FromBase64String(attachment.ContentBytes));


                        return(folder.WebUrl);
                    }
                }

                return(attachmentsUrl);
            }
        }
Beispiel #2
0
        private async Task <IHttpActionResult> SaveAttachmentsWithDistinctTokens(SaveAttachmentRequest request)
        {
            // Validate request
            if (request == null || !request.IsValid())
            {
                return(BadRequest("One or more parameters is missing."));
            }

            // Initialize a Graph client
            GraphServiceClient graphClient = new GraphServiceClient(
                new DelegateAuthenticationProvider(
                    (requestMessage) => {
                // Add the OneDrive access token to each outgoing request
                requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", request.oneDriveToken);
                return(Task.FromResult(0));
            }));

            // First get the attachments from the message
            // The token we get from the add-in is valid for the Outlook API,
            // not the Microsoft Graph API. That means we need to invoke the
            // Outlook endpoint directly, and we can't use the Graph library.
            // Build the request URI to the message attachments collection
            string baseAttachmentsUri = request.outlookRestUrl;

            if (!baseAttachmentsUri.EndsWith("/"))
            {
                baseAttachmentsUri += "/";
            }
            baseAttachmentsUri += "v2.0/me/messages/" + request.messageId + "/attachments/";

            using (var client = new HttpClient())
            {
                foreach (string attachmentId in request.attachmentIds)
                {
                    var getAttachmentReq = new HttpRequestMessage(HttpMethod.Get, baseAttachmentsUri + attachmentId);

                    // Headers
                    getAttachmentReq.Headers.Authorization = new AuthenticationHeaderValue("Bearer", request.outlookToken);
                    getAttachmentReq.Headers.UserAgent.Add(new ProductInfoHeaderValue("AttachmentsDemoOutlookAddin", "1.0"));
                    getAttachmentReq.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                    var result = await client.SendAsync(getAttachmentReq);

                    string json = await result.Content.ReadAsStringAsync();

                    OutlookAttachment attachment = JsonConvert.DeserializeObject <OutlookAttachment>(json);

                    // Is this a file or an Outlook item?
                    if (attachment.Type.ToLower().Contains("itemattachment"))
                    {
                        // Currently REST API doesn't support access to the MIME stream
                        // So for now, just get the JSON representation of the attached item and save it
                        // as a JSON file
                        var getAttachedItemJsonReq = new HttpRequestMessage(HttpMethod.Get, baseAttachmentsUri +
                                                                            attachmentId + "?$expand=Microsoft.OutlookServices.ItemAttachment/Item");

                        getAttachedItemJsonReq.Headers.Authorization = new AuthenticationHeaderValue("Bearer", request.outlookToken);
                        getAttachedItemJsonReq.Headers.UserAgent.Add(new ProductInfoHeaderValue("AttachmentsDemoOutlookAddin", "1.0"));
                        getAttachedItemJsonReq.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                        var getAttachedItemResult = await client.SendAsync(getAttachedItemJsonReq);

                        Stream jsonAttachedItem = await getAttachedItemResult.Content.ReadAsStreamAsync();

                        bool success = await SaveFileToOneDrive(graphClient, attachment.Name + ".json", jsonAttachedItem);

                        if (!success)
                        {
                            return(BadRequest(string.Format("Could not save {0} to OneDrive", attachment.Name)));
                        }
                    }
                    else
                    {
                        // For files, we can build a stream directly from ContentBytes
                        if (attachment.Size < (4 * 1024 * 1024))
                        {
                            MemoryStream fileStream = new MemoryStream(Convert.FromBase64String(attachment.ContentBytes));
                            bool         success    = await SaveFileToOneDrive(graphClient, attachment.Name, fileStream);

                            if (!success)
                            {
                                return(BadRequest(string.Format("Could not save {0} to OneDrive", attachment.Name)));
                            }
                        }
                        else
                        {
                            // TODO: Add code here to handle larger files. See:
                            // https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/item_createuploadsession
                            // and
                            // https://github.com/microsoftgraph/aspnet-snippets-sample/blob/master/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Models/FilesService.cs
                            return(BadRequest("File is too large for simple upload."));
                        }
                    }
                }
            }
            return(Ok());
        }