forked from NLog/NLog
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request NLog#1411 from NLog/improve-mail-from-property
MailTarget: fix "From" errors (bug introduced in NLog 4.3.2)
- Loading branch information
Showing
2 changed files
with
94 additions
and
88 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -92,6 +92,8 @@ public class MailTarget : TargetWithLayoutHeaderAndFooter | |
{ | ||
private const string RequiredPropertyIsEmptyFormat = "After the processing of the MailTarget's '{0}' property it appears to be empty. The email message will not be sent."; | ||
|
||
private Layout _from; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="MailTarget" /> class. | ||
/// </summary> | ||
|
@@ -116,18 +118,31 @@ public MailTarget() | |
/// Gets the mailSettings/smtp configuration from app.config in cases when we need those configuration. | ||
/// E.g when UseSystemNetMailSettings is enabled and we need to read the From attribute from system.net/mailSettings/smtp | ||
/// </summary> | ||
public SmtpSection MailSettings | ||
/// <remarks>Internal for mocking</remarks> | ||
internal SmtpSection SmtpSection | ||
{ | ||
get | ||
{ | ||
if (null == _currentailSettings) | ||
if (_currentailSettings == null) | ||
{ | ||
_currentailSettings = System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).GetSection("system.net/mailSettings/smtp") as SmtpSection; | ||
try | ||
{ | ||
_currentailSettings = System.Configuration.ConfigurationManager.GetSection("system.net/mailSettings/smtp") as SmtpSection; | ||
} | ||
catch (Exception ex) | ||
{ | ||
InternalLogger.Warn(ex, "reading 'From' from .config failed."); | ||
|
||
if (ex.MustBeRethrown()) | ||
{ | ||
throw; | ||
} | ||
_currentailSettings = new SmtpSection(); | ||
} | ||
} | ||
|
||
return _currentailSettings; | ||
} | ||
|
||
set { _currentailSettings = value; } | ||
} | ||
#endif | ||
|
@@ -136,8 +151,30 @@ public SmtpSection MailSettings | |
/// Gets or sets sender's email address (e.g. [email protected]). | ||
/// </summary> | ||
/// <docgen category='Message Options' order='10' /> | ||
[RequiredParameter] | ||
public Layout From { get; set; } | ||
public Layout From | ||
{ | ||
get | ||
{ | ||
#if !__ANDROID__ && !__IOS__ | ||
if (UseSystemNetMailSettings) | ||
{ | ||
// In contrary to other settings, System.Net.Mail.SmtpClient doesn't read the 'From' attribute from the system.net/mailSettings/smtp section in the config file. | ||
// Thus, when UseSystemNetMailSettings is enabled we have to read the configuration section of system.net/mailSettings/smtp to initialize the 'From' address. | ||
// It will do so only if the 'From' attribute in system.net/mailSettings/smtp is not empty. | ||
|
||
//only use from config when not set in current | ||
if (_from == null) | ||
{ | ||
var from = SmtpSection.From; | ||
if (from == null) return null; | ||
return from; | ||
} | ||
} | ||
#endif | ||
return _from; | ||
} | ||
set { _from = value; } | ||
} | ||
|
||
/// <summary> | ||
/// Gets or sets recipients' email addresses separated by semicolons (e.g. [email protected];[email protected]). | ||
|
@@ -317,20 +354,7 @@ protected override void InitializeTarget() | |
base.InitializeTarget(); | ||
} | ||
|
||
/// <summary> | ||
/// In contrary to other settings, System.Net.Mail.SmtpClient doesn't read the 'From' attribute from the system.net/mailSettings/smtp section in the config file. | ||
/// Thus, when UseSystemNetMailSettings is enabled we have to read the configuration section of system.net/mailSettings/smtp to initialize the 'From' address. | ||
/// It will do so only if the 'From' attribute in system.net/mailSettings/smtp is not empty. | ||
/// </summary> | ||
private void ConfigureFrom() | ||
{ | ||
#if !__ANDROID__ && !__IOS__ | ||
if (!string.IsNullOrEmpty(MailSettings.From)) | ||
{ | ||
From = MailSettings.From; | ||
} | ||
#endif | ||
} | ||
|
||
|
||
/// <summary> | ||
/// Create mail and send with SMTP | ||
|
@@ -360,10 +384,6 @@ private void ProcessSingleMailMessage([NotNull] List<AsyncLogEventInfo> events) | |
{ | ||
ConfigureMailClient(lastEvent, client); | ||
} | ||
else | ||
{ | ||
ConfigureFrom(); | ||
} | ||
|
||
InternalLogger.Debug("Sending mail to {0} using {1}:{2} (ssl={3})", msg.To, client.Host, client.Port, client.EnableSsl); | ||
InternalLogger.Trace(" Subject: '{0}'", msg.Subject); | ||
|
@@ -440,6 +460,7 @@ private StringBuilder CreateBodyBuffer(IEnumerable<AsyncLogEventInfo> events, Lo | |
/// </summary> | ||
/// <param name="lastEvent">last event for username/password</param> | ||
/// <param name="client">client to set properties on</param> | ||
/// <remarks>Configure not at <see cref="InitializeTarget"/>, as the properties could have layout renderers.</remarks> | ||
internal void ConfigureMailClient(LogEventInfo lastEvent, ISmtpClient client) | ||
{ | ||
CheckRequiredParameters(); | ||
|
@@ -523,14 +544,17 @@ private void CheckRequiredParameters() | |
{ | ||
if (!this.UseSystemNetMailSettings && this.SmtpServer == null && this.DeliveryMethod == SmtpDeliveryMethod.Network) | ||
{ | ||
throw new NLogConfigurationException( | ||
string.Format("The MailTarget's '{0}' properties are not set - but needed because useSystemNetMailSettings=false and DeliveryMethod=Network. The email message will not be sent.", "SmtpServer")); | ||
throw new NLogConfigurationException("The MailTarget's '{0}' properties are not set - but needed because useSystemNetMailSettings=false and DeliveryMethod=Network. The email message will not be sent.", "SmtpServer"); | ||
} | ||
|
||
if (!this.UseSystemNetMailSettings && string.IsNullOrEmpty(this.PickupDirectoryLocation) && this.DeliveryMethod == SmtpDeliveryMethod.SpecifiedPickupDirectory) | ||
{ | ||
throw new NLogConfigurationException( | ||
string.Format("The MailTarget's '{0}' properties are not set - but needed because useSystemNetMailSettings=false and DeliveryMethod=SpecifiedPickupDirectory. The email message will not be sent.", "PickupDirectoryLocation")); | ||
throw new NLogConfigurationException("The MailTarget's '{0}' properties are not set - but needed because useSystemNetMailSettings=false and DeliveryMethod=SpecifiedPickupDirectory. The email message will not be sent.", "PickupDirectoryLocation"); | ||
} | ||
|
||
if (this.From == null) | ||
{ | ||
throw new NLogConfigurationException(RequiredPropertyIsEmptyFormat, "From"); | ||
} | ||
} | ||
|
||
|
@@ -568,6 +592,8 @@ private static void AppendLayout(StringBuilder sb, LogEventInfo logEvent, Layout | |
sb.Append(layout.Render(logEvent)); | ||
} | ||
|
||
|
||
|
||
/// <summary> | ||
/// Create the mailmessage with the addresses, properties and body. | ||
/// </summary> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,7 +31,6 @@ | |
// THE POSSIBILITY OF SUCH DAMAGE. | ||
// | ||
|
||
|
||
#if !SILVERLIGHT | ||
|
||
namespace NLog.UnitTests.Targets | ||
|
@@ -47,10 +46,16 @@ namespace NLog.UnitTests.Targets | |
using System.IO; | ||
#if !__ANDROID__ && !__IOS__ | ||
using System.Configuration; | ||
using System.Net.Configuration; | ||
#endif | ||
|
||
public class MailTargetTests : NLogTestBase | ||
{ | ||
public MailTargetTests() | ||
{ | ||
LogManager.ThrowExceptions = true; | ||
} | ||
|
||
[Fact] | ||
public void SimpleEmailTest() | ||
{ | ||
|
@@ -270,6 +275,7 @@ public void PerMessageServer() | |
[Fact] | ||
public void ErrorHandlingTest() | ||
{ | ||
LogManager.ThrowExceptions = false; | ||
var mmt = new MockMailTarget | ||
{ | ||
From = "[email protected]", | ||
|
@@ -441,7 +447,7 @@ public void NoReplaceNewlinesWithBreakInHtmlMail() | |
|
||
var messageSent = mmt.CreatedMocks[0].MessagesSent[0]; | ||
Assert.True(messageSent.IsBodyHtml); | ||
var lines = messageSent.Body.Split(new[] {Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); | ||
var lines = messageSent.Body.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); | ||
Assert.True(lines.Length == 3); | ||
} | ||
|
||
|
@@ -541,8 +547,6 @@ public void MailTarget_WithValidToAndEmptyBcc_SendsMail() | |
|
||
var exceptions = new List<Exception>(); | ||
mmt.WriteAsyncLogEvent(new LogEventInfo(LogLevel.Info, "MyLogger", "log message 1").WithContinuation(exceptions.Add)); | ||
|
||
Assert.Null(exceptions[0]); | ||
Assert.Equal(1, mmt.CreatedMocks.Count); | ||
Assert.Equal(1, mmt.CreatedMocks[0].MessagesSent.Count); | ||
} | ||
|
@@ -560,12 +564,9 @@ public void MailTarget_WithEmptyTo_ThrowsNLogRuntimeException() | |
Body = "${level} ${logger} ${message}", | ||
}; | ||
mmt.Initialize(null); | ||
|
||
var exceptions = new List<Exception>(); | ||
mmt.WriteAsyncLogEvent(new LogEventInfo(LogLevel.Info, "MyLogger", "log message 1").WithContinuation(exceptions.Add)); | ||
Assert.Throws<NLogRuntimeException>(() => mmt.WriteAsyncLogEvent(new LogEventInfo(LogLevel.Info, "MyLogger", "log message 1").WithContinuation(exceptions.Add))); | ||
|
||
Assert.NotNull(exceptions[0]); | ||
Assert.IsType<NLogRuntimeException>(exceptions[0]); | ||
} | ||
|
||
[Fact] | ||
|
@@ -583,10 +584,7 @@ public void MailTarget_WithEmptyFrom_ThrowsNLogRuntimeException() | |
mmt.Initialize(null); | ||
|
||
var exceptions = new List<Exception>(); | ||
mmt.WriteAsyncLogEvent(new LogEventInfo(LogLevel.Info, "MyLogger", "log message 1").WithContinuation(exceptions.Add)); | ||
|
||
Assert.NotNull(exceptions[0]); | ||
Assert.IsType<NLogRuntimeException>(exceptions[0]); | ||
Assert.Throws<NLogRuntimeException>(() => mmt.WriteAsyncLogEvent(new LogEventInfo(LogLevel.Info, "MyLogger", "log message 1").WithContinuation(exceptions.Add))); | ||
} | ||
|
||
[Fact] | ||
|
@@ -604,10 +602,7 @@ public void MailTarget_WithEmptySmtpServer_ThrowsNLogRuntimeException() | |
mmt.Initialize(null); | ||
|
||
var exceptions = new List<Exception>(); | ||
mmt.WriteAsyncLogEvent(new LogEventInfo(LogLevel.Info, "MyLogger", "log message 1").WithContinuation(exceptions.Add)); | ||
|
||
Assert.NotNull(exceptions[0]); | ||
Assert.IsType<NLogRuntimeException>(exceptions[0]); | ||
Assert.Throws<NLogRuntimeException>(() => mmt.WriteAsyncLogEvent(new LogEventInfo(LogLevel.Info, "MyLogger", "log message 1").WithContinuation(exceptions.Add))); | ||
} | ||
|
||
[Fact] | ||
|
@@ -633,7 +628,8 @@ public void MailTargetInitialize_WithoutSpecifiedFrom_ThrowsConfigException() | |
Subject = "Hello from NLog", | ||
SmtpServer = "server1", | ||
SmtpPort = 27, | ||
Body = "${level} ${logger} ${message}" | ||
Body = "${level} ${logger} ${message}", | ||
UseSystemNetMailSettings = false | ||
}; | ||
Assert.Throws<NLogConfigurationException>(() => mmt.Initialize(null)); | ||
} | ||
|
@@ -650,7 +646,7 @@ public void MailTargetInitialize_WithoutSpecifiedSmtpServer_should_not_ThrowsCon | |
Body = "${level} ${logger} ${message}", | ||
UseSystemNetMailSettings = true | ||
}; | ||
|
||
mmt.Initialize(null); | ||
} | ||
|
||
[Fact] | ||
|
@@ -729,7 +725,7 @@ public void MailTarget_UseSystemNetMailSettings_True() | |
|
||
Assert.Equal(mmt.SmtpClientPickUpDirectory, inConfigVal); | ||
} | ||
|
||
[Fact] | ||
public void MailTarget_UseSystemNetMailSettings_True_WithVirtualPath() | ||
{ | ||
|
@@ -745,7 +741,7 @@ public void MailTarget_UseSystemNetMailSettings_True_WithVirtualPath() | |
DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory | ||
}; | ||
mmt.ConfigureMailClient(); | ||
|
||
Assert.NotEqual(inConfigVal, mmt.SmtpClientPickUpDirectory); | ||
var separator = Path.DirectorySeparatorChar; | ||
Assert.Contains(string.Format("{0}App_Data{0}Mail", separator), mmt.SmtpClientPickUpDirectory); | ||
|
@@ -754,84 +750,67 @@ public void MailTarget_UseSystemNetMailSettings_True_WithVirtualPath() | |
#if !__ANDROID__ && !__IOS__ | ||
|
||
[Fact] | ||
public void MailTarget_UseSystemNetMailSettings_True_ReadFromFromConfigFile() | ||
public void MailTarget_UseSystemNetMailSettings_True_ReadFromFromConfigFile_dontoverride() | ||
{ | ||
var configuration = System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); | ||
var section = configuration.GetSection("system.net/mailSettings/smtp") as System.Net.Configuration.SmtpSection; | ||
section.From = "[email protected]"; | ||
|
||
var mmt = new MockMailTarget() | ||
var mmt = new MailTarget() | ||
{ | ||
From = "foo@foo.com", | ||
From = "nlog@foo.com", | ||
To = "[email protected]", | ||
SmtpServer = "server1", | ||
SmtpPort = 27, | ||
Body = "${level} ${logger} ${message}", | ||
UseSystemNetMailSettings = true, | ||
MailSettings = section | ||
SmtpSection = new SmtpSection { From = "[email protected]" } | ||
}; | ||
mmt.Initialize(null); | ||
mmt.ConfigureMailClient(); | ||
Assert.Equal("'[email protected]'", mmt.From.ToString()); | ||
|
||
var exceptions = new List<Exception>(); | ||
mmt.WriteAsyncLogEvent(new LogEventInfo(LogLevel.Debug, "MyLogger", "log message").WithContinuation(exceptions.Add)); | ||
mmt.Initialize(null); | ||
|
||
Assert.Equal("'foo@bar.com'", mmt.From.ToString()); | ||
Assert.Equal("'nlog@foo.com'", mmt.From.ToString()); | ||
} | ||
|
||
[Fact] | ||
public void MailTarget_UseSystemNetMailSettings_False_ReadFromFromConfigFile() | ||
public void MailTarget_UseSystemNetMailSettings_True_ReadFromFromConfigFile() | ||
{ | ||
var configuration = System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); | ||
var section = configuration.GetSection("system.net/mailSettings/smtp") as System.Net.Configuration.SmtpSection; | ||
section.From = "[email protected]"; | ||
|
||
var mmt = new MockMailTarget() | ||
var mmt = new MailTarget() | ||
{ | ||
From = "[email protected]", | ||
From = null, | ||
To = "[email protected]", | ||
SmtpServer = "server1", | ||
SmtpPort = 27, | ||
Body = "${level} ${logger} ${message}", | ||
UseSystemNetMailSettings = false, | ||
MailSettings = section | ||
UseSystemNetMailSettings = true, | ||
SmtpSection = new SmtpSection { From = "[email protected]" } | ||
}; | ||
mmt.Initialize(null); | ||
mmt.ConfigureMailClient(); | ||
Assert.Equal("'[email protected]'", mmt.From.ToString()); | ||
|
||
var exceptions = new List<Exception>(); | ||
mmt.WriteAsyncLogEvent(new LogEventInfo(LogLevel.Debug, "MyLogger", "log message").WithContinuation(exceptions.Add)); | ||
mmt.Initialize(null); | ||
|
||
Assert.Equal("'foo@foo.com'", mmt.From.ToString()); | ||
Assert.Equal("'config@foo.com'", mmt.From.ToString()); | ||
} | ||
|
||
[Fact] | ||
public void MailTarget_UseSystemNetMailSettings_True_KeepOverridenFiles() | ||
public void MailTarget_UseSystemNetMailSettings_False_ReadFromFromConfigFile() | ||
{ | ||
var configuration = System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); | ||
var section = configuration.GetSection("system.net/mailSettings/smtp") as System.Net.Configuration.SmtpSection; | ||
section.From = null; | ||
|
||
var mmt = new MockMailTarget() | ||
var mmt = new MailTarget() | ||
{ | ||
From = "[email protected]", | ||
From = null, | ||
To = "[email protected]", | ||
SmtpServer = "server1", | ||
SmtpPort = 27, | ||
Body = "${level} ${logger} ${message}", | ||
UseSystemNetMailSettings = true, | ||
MailSettings = section | ||
UseSystemNetMailSettings = false, | ||
SmtpSection = new SmtpSection { From = "[email protected]" } | ||
}; | ||
Assert.Null(mmt.From); | ||
|
||
mmt.Initialize(null); | ||
mmt.ConfigureMailClient(); | ||
|
||
var exceptions = new List<Exception>(); | ||
mmt.WriteAsyncLogEvent(new LogEventInfo(LogLevel.Debug, "MyLogger", "log message").WithContinuation(exceptions.Add)); | ||
Assert.Throws <NLogConfigurationException>(() => mmt.Initialize(null)); | ||
|
||
Assert.Equal("'[email protected]'", mmt.From.ToString()); | ||
} | ||
|
||
#endif | ||
|
||
[Fact] | ||
|
@@ -925,6 +904,7 @@ internal override ISmtpClient CreateSmtpClient() | |
return client; | ||
} | ||
|
||
|
||
public void ConfigureMailClient() | ||
{ | ||
if (UseSystemNetMailSettings) return; | ||
|