From 4f637e8e27636bb858fb97eab30ded70d336ea65 Mon Sep 17 00:00:00 2001 From: Graham Mueller Date: Sat, 16 Sep 2017 10:24:15 -0500 Subject: [PATCH 1/9] First pass cleanup. * Support adding a single Attachment object * Clean up if else, just "if doesn't exist, create" then add item * Same for multiple, make if not exists, then add range * There likely would have been bug in the multiple because it was assigning a list passed in, which could have been modified from outside * Remove return at end of function in void functions --- src/SendGrid/Helpers/Mail/SendGridMessage.cs | 27 +++++++++----------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/SendGrid/Helpers/Mail/SendGridMessage.cs b/src/SendGrid/Helpers/Mail/SendGridMessage.cs index a6b0cab1f..5ab254d34 100644 --- a/src/SendGrid/Helpers/Mail/SendGridMessage.cs +++ b/src/SendGrid/Helpers/Mail/SendGridMessage.cs @@ -1003,19 +1003,21 @@ public void AddAttachment(string filename, string content, string type = null, s ContentId = content_id }; + this.AddAttachment(attachment); + } + + /// + /// Add an attachment to the email. + /// + /// An Attachment. + public void AddAttachment(Attachment attachment) + { if (this.Attachments == null) { - this.Attachments = new List() - { - attachment - }; - } - else - { - this.Attachments.Add(attachment); + this.Attachments = new List(); } - return; + this.Attachments.Add(attachment); } /// @@ -1027,14 +1029,9 @@ public void AddAttachments(List attachments) if (this.Attachments == null) { this.Attachments = new List(); - this.Attachments = attachments; - } - else - { - this.Attachments.AddRange(attachments); } - return; + this.Attachments.AddRange(attachments); } /// From 43b1b1f0559cdc85c25d85c28cbb3d4cc7c0d1a7 Mon Sep 17 00:00:00 2001 From: Graham Mueller Date: Sat, 16 Sep 2017 10:29:11 -0500 Subject: [PATCH 2/9] Update param description. This caused confusion internally, so a little more detail would help. --- src/SendGrid/Helpers/Mail/SendGridMessage.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SendGrid/Helpers/Mail/SendGridMessage.cs b/src/SendGrid/Helpers/Mail/SendGridMessage.cs index 5ab254d34..bae460f6a 100644 --- a/src/SendGrid/Helpers/Mail/SendGridMessage.cs +++ b/src/SendGrid/Helpers/Mail/SendGridMessage.cs @@ -987,17 +987,17 @@ public void AddContents(List contents) /// /// Add an attachment to the email. /// - /// The filename of the attachment. - /// The Base64 encoded content of the attachment. + /// The filename the attachment will display in the email. + /// The Base64 encoded content of the attachment. /// The mime type of the content you are attaching. For example, application/pdf or image/jpeg. /// The content-disposition of the attachment specifying how you would like the attachment to be displayed. For example, "inline" results in the attached file being displayed automatically within the message while "attachment" results in the attached file requiring some action to be taken before it is displayed (e.g. opening or downloading the file). Defaults to "attachment". Can be either "attachment" or "inline". /// A unique id that you specify for the attachment. This is used when the disposition is set to "inline" and the attachment is an image, allowing the file to be displayed within the body of your email. Ex: ]]> - public void AddAttachment(string filename, string content, string type = null, string disposition = null, string content_id = null) + public void AddAttachment(string filename, string base64Content, string type = null, string disposition = null, string content_id = null) { var attachment = new Attachment() { Filename = filename, - Content = content, + Content = base64Content, Type = type, Disposition = disposition, ContentId = content_id From 869af0324ef0bd9fb6a8e5129dde3ce8f5c838a0 Mon Sep 17 00:00:00 2001 From: Graham Mueller Date: Sat, 16 Sep 2017 11:42:20 -0500 Subject: [PATCH 3/9] Add method for adding attachment streams. Read a stream's bytes, base64 encode, attach. Arrange usings. --- src/SendGrid/Helpers/Mail/SendGridMessage.cs | 43 +++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/src/SendGrid/Helpers/Mail/SendGridMessage.cs b/src/SendGrid/Helpers/Mail/SendGridMessage.cs index bae460f6a..7f4a827cf 100644 --- a/src/SendGrid/Helpers/Mail/SendGridMessage.cs +++ b/src/SendGrid/Helpers/Mail/SendGridMessage.cs @@ -5,11 +5,14 @@ namespace SendGrid.Helpers.Mail { - using Model; - using Newtonsoft.Json; using System; using System.Collections.Generic; + using System.IO; using System.Linq; + using System.Threading; + using System.Threading.Tasks; + using Model; + using Newtonsoft.Json; /// /// Class SendGridMessage builds an object that sends an email through SendGrid. @@ -17,6 +20,9 @@ namespace SendGrid.Helpers.Mail [JsonObject(IsReference = false)] public class SendGridMessage { + // Maximum attachment size is limited to 30MB + private const int MaxAttachmentSize = 30 * 1024 * 1024; + /// /// Gets or sets an email object containing the email address and name of the sender. Unicode encoding is not supported for the from field. /// @@ -984,6 +990,39 @@ public void AddContents(List contents) return; } + /// + /// Add an attachment from a stream to the email. No attachment will be added in the case that the stream cannot be read, or if the attachment length exceeds SendGrid's maximum size (30MB). + /// + /// The filename the attachment will display in the email. + /// The stream to use as content of the attachment. + /// The mime type of the content you are attaching. For example, application/pdf or image/jpeg. + /// The content-disposition of the attachment specifying how you would like the attachment to be displayed. For example, "inline" results in the attached file being displayed automatically within the message while "attachment" results in the attached file requiring some action to be taken before it is displayed (e.g. opening or downloading the file). Defaults to "attachment". Can be either "attachment" or "inline". + /// A unique id that you specify for the attachment. This is used when the disposition is set to "inline" and the attachment is an image, allowing the file to be displayed within the body of your email. Ex: ]]> + /// A cancellation token which can notify if the task should be canceled. + /// A representing the asynchronous operation. + public async Task AddAttachmentAsync(string filename, Stream contentStream, string type = null, string disposition = null, string content_id = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Stream doesn't want us to read it, can't do anything else here + if (!contentStream.CanRead) + { + return; + } + + if (contentStream.Length > MaxAttachmentSize) + { + return; + } + + var streamBytes = new byte[contentStream.Length]; + + // Read all the bytes. Note that we can safely case the length as an int, as the maximum allowed is less than int.MaxValue + await contentStream.ReadAsync(streamBytes, 0, (int)contentStream.Length, cancellationToken); + + var base64Content = Convert.ToBase64String(streamBytes); + + this.AddAttachment(filename, base64Content, type, disposition, content_id); + } + /// /// Add an attachment to the email. /// From 2709194d844e22ea3e3fa5716d7433beef3113c3 Mon Sep 17 00:00:00 2001 From: Graham Mueller Date: Mon, 18 Sep 2017 09:09:45 -0500 Subject: [PATCH 4/9] Remove extra logic around length. Instead, just truncate long to int. --- src/SendGrid/Helpers/Mail/SendGridMessage.cs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/SendGrid/Helpers/Mail/SendGridMessage.cs b/src/SendGrid/Helpers/Mail/SendGridMessage.cs index 7f4a827cf..474e45030 100644 --- a/src/SendGrid/Helpers/Mail/SendGridMessage.cs +++ b/src/SendGrid/Helpers/Mail/SendGridMessage.cs @@ -20,9 +20,6 @@ namespace SendGrid.Helpers.Mail [JsonObject(IsReference = false)] public class SendGridMessage { - // Maximum attachment size is limited to 30MB - private const int MaxAttachmentSize = 30 * 1024 * 1024; - /// /// Gets or sets an email object containing the email address and name of the sender. Unicode encoding is not supported for the from field. /// @@ -991,7 +988,7 @@ public void AddContents(List contents) } /// - /// Add an attachment from a stream to the email. No attachment will be added in the case that the stream cannot be read, or if the attachment length exceeds SendGrid's maximum size (30MB). + /// Add an attachment from a stream to the email. No attachment will be added in the case that the stream cannot be read. Streams of length greater than int.MaxValue are truncated /// /// The filename the attachment will display in the email. /// The stream to use as content of the attachment. @@ -1008,15 +1005,10 @@ public void AddContents(List contents) return; } - if (contentStream.Length > MaxAttachmentSize) - { - return; - } - - var streamBytes = new byte[contentStream.Length]; + var contentLength = Convert.ToInt32(contentStream.Length); + var streamBytes = new byte[contentLength]; - // Read all the bytes. Note that we can safely case the length as an int, as the maximum allowed is less than int.MaxValue - await contentStream.ReadAsync(streamBytes, 0, (int)contentStream.Length, cancellationToken); + await contentStream.ReadAsync(streamBytes, 0, contentLength, cancellationToken); var base64Content = Convert.ToBase64String(streamBytes); From 0540d7c7e3328545e0d4ae94462fd25b976e4530 Mon Sep 17 00:00:00 2001 From: Graham Mueller Date: Mon, 18 Sep 2017 09:30:49 -0500 Subject: [PATCH 5/9] Whoops, this didn't go through on the last commit. More changes around stream truncation and not handling size. --- src/SendGrid/Helpers/Mail/SendGridMessage.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SendGrid/Helpers/Mail/SendGridMessage.cs b/src/SendGrid/Helpers/Mail/SendGridMessage.cs index 474e45030..f7e9bb16a 100644 --- a/src/SendGrid/Helpers/Mail/SendGridMessage.cs +++ b/src/SendGrid/Helpers/Mail/SendGridMessage.cs @@ -988,7 +988,7 @@ public void AddContents(List contents) } /// - /// Add an attachment from a stream to the email. No attachment will be added in the case that the stream cannot be read. Streams of length greater than int.MaxValue are truncated + /// Add an attachment from a stream to the email. No attachment will be added in the case that the stream cannot be read. Streams of length greater than int.MaxValue are truncated. /// /// The filename the attachment will display in the email. /// The stream to use as content of the attachment. From 89f89af2d415865096c8fa9293c43fedb4d3b42a Mon Sep 17 00:00:00 2001 From: Graham Mueller Date: Mon, 6 Nov 2017 11:55:29 -0600 Subject: [PATCH 6/9] Null / empty check. Make class interface more generic. --- src/SendGrid/Helpers/Mail/SendGridMessage.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/SendGrid/Helpers/Mail/SendGridMessage.cs b/src/SendGrid/Helpers/Mail/SendGridMessage.cs index f7e9bb16a..63304496a 100644 --- a/src/SendGrid/Helpers/Mail/SendGridMessage.cs +++ b/src/SendGrid/Helpers/Mail/SendGridMessage.cs @@ -1000,7 +1000,7 @@ public void AddContents(List contents) public async Task AddAttachmentAsync(string filename, Stream contentStream, string type = null, string disposition = null, string content_id = null, CancellationToken cancellationToken = default(CancellationToken)) { // Stream doesn't want us to read it, can't do anything else here - if (!contentStream.CanRead) + if (contentStream == null || !contentStream.CanRead) { return; } @@ -1025,7 +1025,12 @@ public void AddContents(List contents) /// A unique id that you specify for the attachment. This is used when the disposition is set to "inline" and the attachment is an image, allowing the file to be displayed within the body of your email. Ex: ]]> public void AddAttachment(string filename, string base64Content, string type = null, string disposition = null, string content_id = null) { - var attachment = new Attachment() + if (string.IsNullOrWhiteSpace(filename) || string.IsNullOrWhiteSpace(base64Content)) + { + return; + } + + var attachment = new Attachment { Filename = filename, Content = base64Content, @@ -1055,7 +1060,7 @@ public void AddAttachment(Attachment attachment) /// Add attachments to the email. /// /// A list of Attachments. - public void AddAttachments(List attachments) + public void AddAttachments(IEnumerable attachments) { if (this.Attachments == null) { From d2668165d08c4a5a6415b0b44adfc1c3e8cd8848 Mon Sep 17 00:00:00 2001 From: Graham Mueller Date: Mon, 6 Nov 2017 11:55:43 -0600 Subject: [PATCH 7/9] Clean up usings so I can compile. --- tests/SendGrid.Tests/Integration.cs | 11 +++++------ .../Reliability/ReliabilitySettingsTests.cs | 3 +-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/SendGrid.Tests/Integration.cs b/tests/SendGrid.Tests/Integration.cs index 0791ed31d..31cb27957 100644 --- a/tests/SendGrid.Tests/Integration.cs +++ b/tests/SendGrid.Tests/Integration.cs @@ -1,18 +1,17 @@ namespace SendGrid.Tests { - using Helpers.Mail; - using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; using System.Net; using System.Net.Http; - using System.Threading.Tasks; - using Xunit; using System.Threading; - using System.Text; - using Helpers.Reliability; + using System.Threading.Tasks; + using Newtonsoft.Json; using Reliability; + using SendGrid.Helpers.Mail; + using SendGrid.Helpers.Reliability; + using Xunit; using Xunit.Abstractions; public class IntegrationFixture : IDisposable diff --git a/tests/SendGrid.Tests/Reliability/ReliabilitySettingsTests.cs b/tests/SendGrid.Tests/Reliability/ReliabilitySettingsTests.cs index dad52ce78..5357b078f 100644 --- a/tests/SendGrid.Tests/Reliability/ReliabilitySettingsTests.cs +++ b/tests/SendGrid.Tests/Reliability/ReliabilitySettingsTests.cs @@ -1,8 +1,7 @@ namespace SendGrid.Tests.Reliability { using System; - - using Helpers.Reliability; + using SendGrid.Helpers.Reliability; using Xunit; public class ReliabilitySettingsTests From 6525eaa56775ed91a6418b8ff5b9fb0dd02fcc64 Mon Sep 17 00:00:00 2001 From: Graham Mueller Date: Mon, 6 Nov 2017 11:56:02 -0600 Subject: [PATCH 8/9] Add a bunch of tests around the AddAttachment methods. --- .../Helpers/Mail/NonReadableStream.cs | 43 +++ .../Helpers/Mail/SendGridMessageTests.cs | 285 ++++++++++++++++++ 2 files changed, 328 insertions(+) create mode 100644 tests/SendGrid.Tests/Helpers/Mail/NonReadableStream.cs create mode 100644 tests/SendGrid.Tests/Helpers/Mail/SendGridMessageTests.cs diff --git a/tests/SendGrid.Tests/Helpers/Mail/NonReadableStream.cs b/tests/SendGrid.Tests/Helpers/Mail/NonReadableStream.cs new file mode 100644 index 000000000..d8aa47521 --- /dev/null +++ b/tests/SendGrid.Tests/Helpers/Mail/NonReadableStream.cs @@ -0,0 +1,43 @@ +using System.IO; + +namespace SendGrid.Tests.Helpers.Mail +{ + + public class NonReadableStream : Stream + { + public override bool CanRead => false; + + public override bool CanSeek => throw new System.NotImplementedException(); + + public override bool CanWrite => throw new System.NotImplementedException(); + + public override long Length => throw new System.NotImplementedException(); + + public override long Position { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } + + public override void Flush() + { + throw new System.NotImplementedException(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + throw new System.NotImplementedException(); + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new System.NotImplementedException(); + } + + public override void SetLength(long value) + { + throw new System.NotImplementedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + throw new System.NotImplementedException(); + } + } +} diff --git a/tests/SendGrid.Tests/Helpers/Mail/SendGridMessageTests.cs b/tests/SendGrid.Tests/Helpers/Mail/SendGridMessageTests.cs new file mode 100644 index 000000000..c69809098 --- /dev/null +++ b/tests/SendGrid.Tests/Helpers/Mail/SendGridMessageTests.cs @@ -0,0 +1,285 @@ +namespace SendGrid.Tests.Helpers.Mail +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + using SendGrid.Helpers.Mail; + using Xunit; + + public class SendGridMessageTests + { + #region AddAttachment tests + + [Theory] + [InlineData(null, "foo")] + [InlineData("", "foo")] + [InlineData(" ", "foo")] + [InlineData("foo", null)] + [InlineData("foo", "")] + [InlineData("foo", " ")] + public void SendGridMessage_AddAttachment_Doesnt_Add_If_Filename_Or_Content_Are_Missing(string filename, string content) + { + // Arrange + var sut = new SendGridMessage(); + + // Act + sut.AddAttachment(filename, content); + + // Assert + Assert.Null(sut.Attachments); + } + + [Theory] + [InlineData("filename", "content", null, null, null)] + [InlineData("filename", "content", "type", null, null)] + [InlineData("filename", "content", "type", "disposition", null)] + [InlineData("filename", "content", "type", "disposition", "contentId")] + public void SendGridMessage_AddAttachment_Should_Add_Single_Attachment_To_Attachments(string filename, string content, string type, string disposition, string contentId) + { + // Arrange + var sut = new SendGridMessage(); + + // Act + sut.AddAttachment(filename, content, type, disposition, contentId); + + // Assert + Assert.Equal(1, sut.Attachments.Count); + + var attachment = sut.Attachments.First(); + + Assert.Equal(filename, attachment.Filename); + Assert.Equal(content, attachment.Content); + Assert.Equal(type, attachment.Type); + Assert.Equal(disposition, attachment.Disposition); + Assert.Equal(contentId, attachment.ContentId); + } + + public void SendGridMessage_AddAttachment_Doesnt_Touch_Attachment_Passed_In() + { + // Arrange + var sut = new SendGridMessage(); + + var content = "content"; + var contentId = "contentId"; + var disposition = "disposition"; + var filename = "filename"; + var type = "type"; + + var attachment = new Attachment + { + Content = content, + ContentId = contentId, + Disposition = disposition, + Filename = filename, + Type = type + }; + + // Act + sut.AddAttachment(attachment); + + // Assert + Assert.Equal(1, sut.Attachments.Count); + + var addedAttachment = sut.Attachments.First(); + + Assert.Same(attachment, addedAttachment); + Assert.Equal(attachment.Content, addedAttachment.Content); + Assert.Equal(attachment.ContentId, addedAttachment.ContentId); + Assert.Equal(attachment.Disposition, addedAttachment.Disposition); + Assert.Equal(attachment.Filename, addedAttachment.Filename); + Assert.Equal(attachment.Type, addedAttachment.Type); + } + + #endregion + + #region AddAttachments tests + + [Fact] + public void SendGridMessage_AddAttachments_Adds_All_Attachments() + { + // Arrange + var sut = new SendGridMessage(); + + var attachments = new[] + { + new Attachment(), + new Attachment() + }; + + // Act + sut.AddAttachments(attachments); + + // Assert + Assert.Equal(attachments.Length, sut.Attachments.Count); + } + + [Fact] + public void SendGridMessage_AddAttachments_Doesnt_Use_Provided_List_As_Property() + { + // Arrange + var sut = new SendGridMessage(); + + var attachments = new List + { + new Attachment(), + new Attachment() + }; + + // Act + sut.AddAttachments(attachments); + + // Assert + Assert.Equal(attachments.Count(), sut.Attachments.Count); + Assert.NotSame(attachments, sut.Attachments); + } + + [Fact] + public void SendGridMessage_AddAttachments_Doesnt_Touch_Attachments_Passed_In() + { + // Arrange + var sut = new SendGridMessage(); + + var content = "content"; + var contentId = "contentId"; + var disposition = "disposition"; + var filename = "filename"; + var type = "type"; + + var attachment = new Attachment + { + Content = content, + ContentId = contentId, + Disposition = disposition, + Filename = filename, + Type = type + }; + + var attachments = new[] { attachment }; + + // Act + sut.AddAttachments(attachments); + + // Assert + Assert.Equal(1, sut.Attachments.Count); + + var addedAttachment = sut.Attachments.First(); + + Assert.Same(attachment, addedAttachment); + Assert.Equal(attachment.Content, addedAttachment.Content); + Assert.Equal(attachment.ContentId, addedAttachment.ContentId); + Assert.Equal(attachment.Disposition, addedAttachment.Disposition); + Assert.Equal(attachment.Filename, addedAttachment.Filename); + Assert.Equal(attachment.Type, addedAttachment.Type); + } + + #endregion + + #region AddAttachmentAsync tests + + [Fact] + public async Task SendGridMessage_AddAttachmentAsync_Doesnt_Read_Non_Readable_Streams() + { + // Arrange + var sut = new SendGridMessage(); + + var stream = new NonReadableStream(); + + // Act + await sut.AddAttachmentAsync(null, stream); + + // Assert + Assert.Null(sut.Attachments); + } + + [Fact] + public async Task SendGridMessage_AddAttachmentAsync_Adds_Base64_Content_Of_Stream() + { + // Arrange + var sut = new SendGridMessage(); + + var content = "hello world"; + var contentBytes = Encoding.UTF8.GetBytes(content); + var base64EncodedContent = Convert.ToBase64String(contentBytes); + var stream = new MemoryStream(contentBytes); + + // Act + await sut.AddAttachmentAsync("filename", stream); + + // Assert + Assert.Equal(1, sut.Attachments.Count); + + var attachment = sut.Attachments.First(); + + Assert.Equal(attachment.Content, base64EncodedContent); + } + + [Theory] + [InlineData(null, "foo")] + [InlineData("", "foo")] + [InlineData(" ", "foo")] + public async Task SendGridMessage_AddAttachmentAsync_Doesnt_Add_If_Filename_Is_Missing(string filename, string content) + { + // Arrange + var sut = new SendGridMessage(); + + var contentBytes = Encoding.UTF8.GetBytes(content); + var base64EncodedContent = Convert.ToBase64String(contentBytes); + var contentStream = new MemoryStream(contentBytes); + + // Act + await sut.AddAttachmentAsync(filename, contentStream); + + // Assert + Assert.Null(sut.Attachments); + } + + [Fact] + public async Task SendGridMessage_AddAttachmentAsync_Doesnt_Add_If_Content_Stream_Is_Missing() + { + // Arrange + var sut = new SendGridMessage(); + + Stream contentStream = null; + + // Act + await sut.AddAttachmentAsync("filename", contentStream); + + // Assert + Assert.Null(sut.Attachments); + } + + [Theory] + [InlineData("filename", "content", null, null, null)] + [InlineData("filename", "content", "type", null, null)] + [InlineData("filename", "content", "type", "disposition", null)] + [InlineData("filename", "content", "type", "disposition", "contentId")] + public async Task SendGridMessage_AddAttachmentAsync_Should_Add_Single_Attachment_To_Attachments(string filename, string content, string type, string disposition, string contentId) + { + // Arrange + var sut = new SendGridMessage(); + + var contentBytes = Encoding.UTF8.GetBytes(content); + var base64EncodedContent = Convert.ToBase64String(contentBytes); + var contentStream = new MemoryStream(contentBytes); + + // Act + await sut.AddAttachmentAsync(filename, contentStream, type, disposition, contentId); + + // Assert + Assert.Equal(1, sut.Attachments.Count); + + var addedAttachment = sut.Attachments.First(); + + Assert.Equal(base64EncodedContent, addedAttachment.Content); + Assert.Equal(contentId, addedAttachment.ContentId); + Assert.Equal(disposition, addedAttachment.Disposition); + Assert.Equal(filename, addedAttachment.Filename); + Assert.Equal(type, addedAttachment.Type); + } + + #endregion + } +} From babd710a03415cb53c8432685f49964f19f10ccd Mon Sep 17 00:00:00 2001 From: Graham Mueller Date: Mon, 6 Nov 2017 12:00:41 -0600 Subject: [PATCH 9/9] Add example file stream usage in USE_CASES.md --- USE_CASES.md | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/USE_CASES.md b/USE_CASES.md index 90ca5d868..5d064f452 100644 --- a/USE_CASES.md +++ b/USE_CASES.md @@ -28,10 +28,11 @@ namespace Example { private static void Main() { - Execute().Wait(); + ExecuteManualAttachmentAdd().Wait(); + ExecuteStreamAttachmentAdd().Wait(); } - static async Task Execute() + static async Task ExecuteManualAttachmentAdd() { var apiKey = Environment.GetEnvironmentVariable("NAME_OF_THE_ENVIRONMENT_VARIABLE_FOR_YOUR_SENDGRID_KEY"); var client = new SendGridClient(apiKey); @@ -45,6 +46,23 @@ namespace Example msg.AddAttachment("file.txt", file); var response = await client.SendEmailAsync(msg); } + + static async Task ExecuteStreamAttachmentAdd() + { + var apiKey = Environment.GetEnvironmentVariable("NAME_OF_THE_ENVIRONMENT_VARIABLE_FOR_YOUR_SENDGRID_KEY"); + var client = new SendGridClient(apiKey); + var from = new EmailAddress("test@example.com"); + var subject = "Subject"; + var to = new EmailAddress("test@example.com"); + var body = "Email Body"; + var msg = MailHelper.CreateSingleEmail(from, to, subject, body, ""); + + using (var fileStream = File.OpenRead("/Users/username/file.txt")) + { + msg.AddAttachment("file.txt", fileStream); + var response = await client.SendEmailAsync(msg); + } + } } } ``` @@ -656,4 +674,4 @@ Find more information about all of SendGrid's whitelabeling realated doucmentati You can find documentation for how to view your email statistics via the UI [here](https://app.sendgrid.com/statistics) and via API [here](https://github.com/sendgrid/sendgrid-csharp/blob/master/USAGE.md#stats). -Alternatively, we can post events to a URL of your choice via our [Event Webhook](https://sendgrid.com/docs/API_Reference/Webhooks/event.html) about events that occur as SendGrid processes your email. \ No newline at end of file +Alternatively, we can post events to a URL of your choice via our [Event Webhook](https://sendgrid.com/docs/API_Reference/Webhooks/event.html) about events that occur as SendGrid processes your email.