From feac1e046bd4f91a5ec79c34efe3e476f1512aa8 Mon Sep 17 00:00:00 2001 From: axunonb Date: Fri, 6 Mar 2026 20:28:21 +0100 Subject: [PATCH] Fix nullability warnings --- Src/MailMergeLib.Tests/Message_Html.cs | 2 +- Src/MailMergeLib.Tests/Message_Templates.cs | 24 ++++++++--------- .../Message_VariableExceptions.cs | 26 +++++++++---------- Src/MailMergeLib.Tests/Message_Variables.cs | 14 +++++----- Src/MailMergeLib/MailMergeAddress.cs | 6 ++--- Src/MailMergeLib/MailMergeMessage.cs | 17 +++++++----- Src/MailMergeLib/MailMergeSender.cs | 2 +- Src/MailMergeLib/MessageConfig.cs | 2 +- Src/MailMergeLib/Tools.cs | 2 +- 9 files changed, 50 insertions(+), 45 deletions(-) diff --git a/Src/MailMergeLib.Tests/Message_Html.cs b/Src/MailMergeLib.Tests/Message_Html.cs index 63a12df..34c9320 100644 --- a/Src/MailMergeLib.Tests/Message_Html.cs +++ b/Src/MailMergeLib.Tests/Message_Html.cs @@ -207,7 +207,7 @@ public void HtmlMailMergeWithMoreEqualInlineAtt() Assert.Multiple(() => { - Assert.That(new HtmlParser().ParseDocument((string) msg.HtmlBody).All.Count(m => m is IHtmlImageElement), Is.EqualTo(3)); + Assert.That(new HtmlParser().ParseDocument(msg.HtmlBody!).All.Count(m => m is IHtmlImageElement), Is.EqualTo(3)); Assert.That(msg.BodyParts.Count(bp => bp.ContentDisposition?.Disposition == ContentDisposition.Inline && bp.ContentType.IsMimeType("image", "jpeg")), Is.EqualTo(1)); }); diff --git a/Src/MailMergeLib.Tests/Message_Templates.cs b/Src/MailMergeLib.Tests/Message_Templates.cs index 0bb6ef0..1790e15 100644 --- a/Src/MailMergeLib.Tests/Message_Templates.cs +++ b/Src/MailMergeLib.Tests/Message_Templates.cs @@ -22,12 +22,12 @@ public void Template() Assert.That(msg.Subject, Is.EqualTo(mmm.Subject.Replace("{FirstName}", variables["FirstName"]))); // DefaultKey is "Formal" - Assert.That(msg.HtmlBody.Contains(mmm.Templates["Salutation"]["Formal"] + Assert.That(msg.HtmlBody!.Contains(mmm.Templates["Salutation"]["Formal"] .First(t => t.Type == PartType.Html) - .Value.Replace("{FirstName}", variables["FirstName"])), Is.True); - Assert.That(msg.TextBody.Contains(mmm.Templates["Salutation"]["Formal"] + .Value!.Replace("{FirstName}", variables["FirstName"])), Is.True); + Assert.That(msg.TextBody!.Contains(mmm.Templates["Salutation"]["Formal"] .First(t => t.Type == PartType.Plain) - .Value.Replace("{FirstName}", variables["FirstName"])), Is.True); + .Value!.Replace("{FirstName}", variables["FirstName"])), Is.True); }); // Programmacically set the part to use @@ -35,12 +35,12 @@ public void Template() msg = mmm.GetMimeMessage(variables); Assert.Multiple(() => { - Assert.That(msg.HtmlBody.Contains(mmm.Templates["Salutation"]["Dear"] + Assert.That(msg.HtmlBody!.Contains(mmm.Templates["Salutation"]["Dear"] .First(t => t.Type == PartType.Html) - .Value.Replace("{FirstName}", variables["FirstName"])), Is.True); - Assert.That(msg.TextBody.Contains(mmm.Templates["Salutation"]["Dear"] + .Value!.Replace("{FirstName}", variables["FirstName"])), Is.True); + Assert.That(msg.TextBody!.Contains(mmm.Templates["Salutation"]["Dear"] .First(t => t.Type == PartType.Plain) - .Value.Replace("{FirstName}", variables["FirstName"])), Is.True); + .Value!.Replace("{FirstName}", variables["FirstName"])), Is.True); }); // Neither DefaultKey nor Key of the template are set: gets the first part @@ -55,12 +55,12 @@ public void Template() msg = mmm.GetMimeMessage(variables); Assert.Multiple(() => { - Assert.That(msg.HtmlBody.Contains(mmm.Templates["Salutation"]["Hi"] + Assert.That(msg.HtmlBody!.Contains(mmm.Templates["Salutation"]["Hi"] .First(t => t.Type == PartType.Html) - .Value.Replace("{FirstName}", variables["FirstName"])), Is.True); - Assert.That(msg.TextBody.Contains(mmm.Templates["Salutation"]["Hi"] + .Value!.Replace("{FirstName}", variables["FirstName"])), Is.True); + Assert.That(msg.TextBody!.Contains(mmm.Templates["Salutation"]["Hi"] .First(t => t.Type == PartType.Plain) - .Value.Replace("{FirstName}", variables["FirstName"])), Is.True); + .Value!.Replace("{FirstName}", variables["FirstName"])), Is.True); }); } diff --git a/Src/MailMergeLib.Tests/Message_VariableExceptions.cs b/Src/MailMergeLib.Tests/Message_VariableExceptions.cs index be1b684..50b3533 100644 --- a/Src/MailMergeLib.Tests/Message_VariableExceptions.cs +++ b/Src/MailMergeLib.Tests/Message_VariableExceptions.cs @@ -114,12 +114,12 @@ public void Template() Assert.That(msg.Subject, Is.EqualTo(mmm.Subject.Replace("{FirstName}", variables["FirstName"]))); // DefaultKey is "Formal" - Assert.That(msg.HtmlBody.Contains(mmm.Templates["Salutation"]["Formal"] + Assert.That(msg.HtmlBody!.Contains(mmm.Templates["Salutation"]["Formal"] .First(t => t.Type == PartType.Html) - .Value.Replace("{FirstName}", variables["FirstName"])), Is.True); - Assert.That(msg.TextBody.Contains(mmm.Templates["Salutation"]["Formal"] + .Value!.Replace("{FirstName}", variables["FirstName"])), Is.True); + Assert.That(msg.TextBody!.Contains(mmm.Templates["Salutation"]["Formal"] .First(t => t.Type == PartType.Plain) - .Value.Replace("{FirstName}", variables["FirstName"])), Is.True); + .Value!.Replace("{FirstName}", variables["FirstName"])), Is.True); }); // Programmacically set the part to use @@ -127,12 +127,12 @@ public void Template() msg = mmm.GetMimeMessage(variables); Assert.Multiple(() => { - Assert.That(msg.HtmlBody.Contains(mmm.Templates["Salutation"]["Dear"] + Assert.That(msg.HtmlBody!.Contains(mmm.Templates["Salutation"]["Dear"] .First(t => t.Type == PartType.Html) - .Value.Replace("{FirstName}", variables["FirstName"])), Is.True); - Assert.That(msg.TextBody.Contains(mmm.Templates["Salutation"]["Dear"] + .Value!.Replace("{FirstName}", variables["FirstName"])), Is.True); + Assert.That(msg.TextBody!.Contains(mmm.Templates["Salutation"]["Dear"] .First(t => t.Type == PartType.Plain) - .Value.Replace("{FirstName}", variables["FirstName"])), Is.True); + .Value!.Replace("{FirstName}", variables["FirstName"])), Is.True); }); // Neither DefaultKey nore Key of the template are set: gets the first part @@ -147,12 +147,12 @@ public void Template() msg = mmm.GetMimeMessage(variables); Assert.Multiple(() => { - Assert.That(msg.HtmlBody.Contains(mmm.Templates["Salutation"]["Hi"] + Assert.That(msg.HtmlBody!.Contains(mmm.Templates["Salutation"]["Hi"] .First(t => t.Type == PartType.Html) - .Value.Replace("{FirstName}", variables["FirstName"])), Is.True); - Assert.That(msg.TextBody.Contains(mmm.Templates["Salutation"]["Hi"] + .Value!.Replace("{FirstName}", variables["FirstName"])), Is.True); + Assert.That(msg.TextBody!.Contains(mmm.Templates["Salutation"]["Hi"] .First(t => t.Type == PartType.Plain) - .Value.Replace("{FirstName}", variables["FirstName"])), Is.True); + .Value!.Replace("{FirstName}", variables["FirstName"])), Is.True); }); } -} \ No newline at end of file +} diff --git a/Src/MailMergeLib.Tests/Message_Variables.cs b/Src/MailMergeLib.Tests/Message_Variables.cs index 1925a4f..5ade23d 100644 --- a/Src/MailMergeLib.Tests/Message_Variables.cs +++ b/Src/MailMergeLib.Tests/Message_Variables.cs @@ -134,7 +134,7 @@ public void MessagesFromDataRows() Assert.Multiple(() => { Assert.That(mimeMessage.To.ToString().Contains(row["Email"].ToString()!), Is.True); - Assert.That(mimeMessage.TextBody.Contains(text + Assert.That(mimeMessage.TextBody!.Contains(text .Replace("{Email}", row["Email"].ToString()) .Replace("{Continent}", row["Continent"].ToString())), Is.True); }); @@ -166,7 +166,7 @@ public void MessagesFromListOfValueTuples() Assert.Multiple(() => { Assert.That(mimeMessage.To.ToString().Contains(((Dictionary) emailPart)["Email"]), Is.True); - Assert.That(mimeMessage.TextBody.Contains(text.Replace("{Email}", emailPart["Email"]).Replace("{Continent}", continentPart["Continent"])), Is.True); + Assert.That(mimeMessage.TextBody!.Contains(text.Replace("{Email}", emailPart["Email"]).Replace("{Continent}", continentPart["Continent"])), Is.True); }); MailMergeMessage.DisposeFileStreams(mimeMessage); i++; @@ -190,7 +190,7 @@ public void SingleMessageFromValueTuple() Assert.Multiple(() => { Assert.That(mimeMessage.To.ToString().Contains(anonymous.Email), Is.True); - Assert.That(mimeMessage.TextBody.Contains(text.Replace("{Email}", anonymous.Email).Replace("{Continent}", continentPart["Continent"])), Is.True); + Assert.That(mimeMessage.TextBody!.Contains(text.Replace("{Email}", anonymous.Email).Replace("{Continent}", continentPart["Continent"])), Is.True); }); MailMergeMessage.DisposeFileStreams(mimeMessage); } @@ -225,7 +225,7 @@ public void MessagesFromList() Assert.That(mimeMessage.TextBody == string.Format( $"This is the plain text part for {recipients[cnt].Name} ({recipients[cnt].Email})"), Is.True); - Assert.That(mimeMessage.HtmlBody.Contains(string.Format( + Assert.That(mimeMessage.HtmlBody!.Contains(string.Format( $"This is the plain text part for {recipients[cnt].Name} ({recipients[cnt].Email})")), Is.True); Assert.That(mimeMessage.To.ToString().Contains(recipients[cnt].Name) && mimeMessage.To.ToString().Contains(recipients[cnt].Email), Is.True); @@ -268,7 +268,7 @@ public void MessagesFromJsonArray() Assert.Multiple(() => { Assert.That(mimeMessage.TextBody == string.Format($"This is the plain text part for {recipients[cnt]["Name"]} ({recipients[cnt]["Email"]})"), Is.True); - Assert.That(mimeMessage.HtmlBody.Contains(string.Format($"This is the plain text part for {recipients[cnt]["Name"]} ({recipients[cnt]["Email"]})")), Is.True); + Assert.That(mimeMessage.HtmlBody!.Contains(string.Format($"This is the plain text part for {recipients[cnt]["Name"]} ({recipients[cnt]["Email"]})")), Is.True); Assert.That(mimeMessage.To.ToString().Contains(recipients[cnt]["Name"]!.ToString()) && mimeMessage.To.ToString().Contains(recipients[cnt]["Email"]!.ToString()), Is.True); }); MailMergeMessage.DisposeFileStreams(mimeMessage); @@ -295,9 +295,9 @@ public void Disabled_Formatter_Should_Maintain_Variable_Placeholders() Assert.Multiple(() => { - Assert.That(mimeMessage.Subject.Contains("Subject for {Continent}"), Is.True); + Assert.That(mimeMessage.Subject!.Contains("Subject for {Continent}"), Is.True); Assert.That(mimeMessage.To.ToString().Contains("{Name}"), Is.True); - Assert.That(mimeMessage.TextBody.Contains(text), Is.True); + Assert.That(mimeMessage.TextBody!.Contains(text), Is.True); }); MailMergeMessage.DisposeFileStreams(mimeMessage); } diff --git a/Src/MailMergeLib/MailMergeAddress.cs b/Src/MailMergeLib/MailMergeAddress.cs index a34ea2f..a7618a0 100644 --- a/Src/MailMergeLib/MailMergeAddress.cs +++ b/Src/MailMergeLib/MailMergeAddress.cs @@ -123,8 +123,8 @@ internal string? DisplayNameCharacterEncodingName } return displayName != null - ? new MailboxAddress(DisplayNameCharacterEncoding, displayName, address) - : new MailboxAddress(DisplayNameCharacterEncoding, address, address); + ? new MailboxAddress(DisplayNameCharacterEncoding ?? Encoding.UTF8, displayName, address) + : new MailboxAddress(DisplayNameCharacterEncoding ?? Encoding.UTF8, address, address); } #region *** Equality *** @@ -167,4 +167,4 @@ public override int GetHashCode() } #endregion -} \ No newline at end of file +} diff --git a/Src/MailMergeLib/MailMergeMessage.cs b/Src/MailMergeLib/MailMergeMessage.cs index cd27602..49f4adb 100644 --- a/Src/MailMergeLib/MailMergeMessage.cs +++ b/Src/MailMergeLib/MailMergeMessage.cs @@ -809,7 +809,7 @@ private void AddAddressesToMailMessage(MimeMessage mimeMessage, object? dataItem if (Config.StandardFromAddress != null) { Config.StandardFromAddress.Address = SearchAndReplaceVars(Config.StandardFromAddress.Address, dataItem); - Config.StandardFromAddress.Name = SearchAndReplaceVars(Config.StandardFromAddress.Name, dataItem); + Config.StandardFromAddress.Name = SearchAndReplaceVars(Config.StandardFromAddress.Name ?? string.Empty, dataItem); mimeMessage.From.Add(Config.StandardFromAddress); } @@ -832,6 +832,9 @@ private void AddAddressesToMailMessage(MimeMessage mimeMessage, object? dataItem if (Config.IgnoreIllegalRecipientAddresses && mailboxAddr == null) continue; + if (mailboxAddr == null) + continue; + switch (mmAddr.AddrType) { case MailAddressType.To: @@ -848,11 +851,13 @@ private void AddAddressesToMailMessage(MimeMessage mimeMessage, object? dataItem break; case MailAddressType.ConfirmReadingTo: mimeMessage.Headers.RemoveAll(HeaderId.DispositionNotificationTo); - mimeMessage.Headers.Add(HeaderId.DispositionNotificationTo, mailboxAddr?.Address); + if (mailboxAddr.Address != null) + mimeMessage.Headers.Add(HeaderId.DispositionNotificationTo, mailboxAddr.Address); break; case MailAddressType.ReturnReceiptTo: mimeMessage.Headers.RemoveAll(HeaderId.ReturnReceiptTo); - mimeMessage.Headers.Add(HeaderId.ReturnReceiptTo, mailboxAddr?.Address); + if (mailboxAddr.Address != null) + mimeMessage.Headers.Add(HeaderId.ReturnReceiptTo, mailboxAddr.Address); break; case MailAddressType.Sender: mimeMessage.Sender = mailboxAddr; @@ -878,12 +883,12 @@ private void AddAttributesToMailMessage(MimeMessage mimeMessage, object? dataIte if (!string.IsNullOrEmpty(Config.Xmailer)) { - mimeMessage.Headers.Replace(HeaderId.XMailer, Config.CharacterEncoding, Config.Xmailer); + mimeMessage.Headers.Replace(HeaderId.XMailer, Config.CharacterEncoding, Config.Xmailer!); } if (!string.IsNullOrEmpty(Config.Organization)) { - mimeMessage.Headers.Replace(HeaderId.Organization, Config.CharacterEncoding, Config.Organization); + mimeMessage.Headers.Replace(HeaderId.Organization, Config.CharacterEncoding, Config.Organization!); } // collect any headers already present, e.g. headers for mailbox addresses like return-receipt @@ -1001,7 +1006,7 @@ public override int GetHashCode() { } /// - /// Compares the MailMergeMessage with an other instance of MailMergeMessage for equality. + /// Compares the MailMergeMessage with another instance of MailMergeMessage for equality. /// /// /// Returns true, if both instances are equal, else false. diff --git a/Src/MailMergeLib/MailMergeSender.cs b/Src/MailMergeLib/MailMergeSender.cs index a9ef373..d10a3ff 100644 --- a/Src/MailMergeLib/MailMergeSender.cs +++ b/Src/MailMergeLib/MailMergeSender.cs @@ -362,7 +362,7 @@ internal async Task SendMimeMessageAsync(SmtpClient smtpClient, MimeMessage mime foreach (var mimeEntity in mimeMsg.Attachments) { var att = mimeEntity as MimePart; - att?.Content.Stream.Dispose(); + att?.Content?.Stream?.Dispose(); } if (sendException != null) diff --git a/Src/MailMergeLib/MessageConfig.cs b/Src/MailMergeLib/MessageConfig.cs index 8e198ae..91ac689 100644 --- a/Src/MailMergeLib/MessageConfig.cs +++ b/Src/MailMergeLib/MessageConfig.cs @@ -128,7 +128,7 @@ public string FileBaseDirectory private string? StandardFromAddressText { get => StandardFromAddress?.ToString(); - set => StandardFromAddress = !string.IsNullOrEmpty(value) ? MailboxAddress.Parse(ParserOptions.Default, value) : null; + set => StandardFromAddress = !string.IsNullOrEmpty(value) ? MailboxAddress.Parse(ParserOptions.Default, value!) : null; } #pragma warning restore IDE0051 diff --git a/Src/MailMergeLib/Tools.cs b/Src/MailMergeLib/Tools.cs index 0799983..866d99d 100644 --- a/Src/MailMergeLib/Tools.cs +++ b/Src/MailMergeLib/Tools.cs @@ -240,7 +240,7 @@ public static string WrapLine(string input, int length) public static void ParseMailAddress(string inputAddr, out string displayName, out string address) { var mbAddr = MailboxAddress.Parse(ParserOptions.Default, inputAddr); - displayName = mbAddr.Name; + displayName = mbAddr.Name ?? string.Empty; address = mbAddr.Address; }