1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.Components
.Common
.EmailSender
.Smtp
18 using System
.Collections
;
19 using System
.ComponentModel
;
22 using System
.Net
.Mail
;
25 /// Uses Smtp to send emails.
27 public class SmtpSender
: IEmailSender
29 private SmtpClient smtpClient
;
30 private bool asyncSend
= false;
31 private bool configured
;
32 private string hostname
;
33 private int port
= 25;
34 private NetworkCredential credentials
= new NetworkCredential();
37 /// This service implementation
38 /// requires a host name in order to work
40 /// <param name="hostname">The smtp server name</param>
41 public SmtpSender(string hostname
)
43 this.hostname
= hostname
;
45 smtpClient
= new SmtpClient(hostname
);
49 /// Gets or sets the port used to
50 /// access the SMTP server
59 /// Gets the hostname.
61 /// <value>The hostname.</value>
62 public string Hostname
64 get { return hostname; }
68 /// Gets or sets a value which is used to
69 /// configure if emails are going to be sent asyncrhonously or not.
73 get { return asyncSend; }
74 set { asyncSend = value; }
78 /// Gets or sets a value that specifies
79 /// the amount of time after which a synchronous Send call times out.
83 get { return smtpClient.Timeout; }
84 set { smtpClient.Timeout = value; }
90 /// <exception cref="ArgumentNullException">If any of the parameters is null</exception>
91 /// <param name="from">From field</param>
92 /// <param name="to">To field</param>
93 /// <param name="subject">e-mail's subject</param>
94 /// <param name="messageText">message's body</param>
95 public void Send(String
from, String to
, String subject
, String messageText
)
97 if (from == null) throw new ArgumentNullException("from");
98 if (to
== null) throw new ArgumentNullException("to");
99 if (subject
== null) throw new ArgumentNullException("subject");
100 if (messageText
== null) throw new ArgumentNullException("messageText");
102 Send(new Message(from, to
, subject
, messageText
));
108 /// <exception cref="ArgumentNullException">If the message is null</exception>
109 /// <param name="message">Message instance</param>
110 public void Send(Message message
)
112 if (message
== null) throw new ArgumentNullException("message");
114 ConfigureSender(message
);
118 // The MailMessage must be diposed after sending the email.
119 // The code creates a delegate for deleting the mail and adds
120 // it to the smtpClient.
121 // After the mail is sent, the message is disposed and the
122 // eventHandler removed from the smtpClient.
123 MailMessage msg
= CreateMailMessage(message
);
124 Guid msgGuid
= new Guid();
125 SendCompletedEventHandler sceh
= null;
126 sceh
= delegate(object sender
, AsyncCompletedEventArgs e
)
128 if (msgGuid
== (Guid
)e
.UserState
)
130 // The handler itself, cannot be null, test omitted
131 smtpClient
.SendCompleted
-= sceh
;
133 smtpClient
.SendCompleted
+= sceh
;
134 smtpClient
.SendAsync(msg
, msgGuid
);
138 using (MailMessage msg
= CreateMailMessage(message
))
140 smtpClient
.Send(msg
);
145 public void Send(Message
[] messages
)
147 foreach (Message message
in messages
)
154 /// Converts a message from Castle.Components.Common.EmailSender.Message type
155 /// to System.Web.Mail.MailMessage
157 /// <param name="message">The message to convert.</param>
158 /// <returns>The converted message .</returns>
159 private MailMessage
CreateMailMessage(Message message
)
161 MailMessage mailMessage
= new MailMessage(message
.From
, message
.To
.Replace(';', ','));
163 if (!String
.IsNullOrEmpty(message
.Cc
))
165 mailMessage
.CC
.Add(message
.Cc
);
168 if (!String
.IsNullOrEmpty(message
.Bcc
))
170 mailMessage
.Bcc
.Add(message
.Bcc
);
173 mailMessage
.Subject
= message
.Subject
;
174 mailMessage
.Body
= message
.Body
;
175 mailMessage
.BodyEncoding
= message
.Encoding
;
176 mailMessage
.IsBodyHtml
= (message
.Format
== Format
.Html
);
177 mailMessage
.Priority
= (MailPriority
)Enum
.Parse(typeof(MailPriority
), message
.Priority
.ToString());
179 foreach (DictionaryEntry entry
in message
.Headers
)
181 mailMessage
.Headers
.Add((string)entry
.Key
, (string)entry
.Value
);
184 foreach (MessageAttachment attachment
in message
.Attachments
)
186 Attachment mailAttach
;
188 if (attachment
.Stream
!= null)
190 mailAttach
= new Attachment(attachment
.Stream
, attachment
.MediaType
);
194 mailAttach
= new Attachment(attachment
.FileName
, attachment
.MediaType
);
197 mailMessage
.Attachments
.Add(mailAttach
);
200 if (message
.Resources
!= null && message
.Resources
.Count
> 0)
202 AlternateView htmlView
= AlternateView
.CreateAlternateViewFromString(message
.Body
, message
.Encoding
, "text/html");
203 foreach (string id
in message
.Resources
.Keys
)
205 LinkedResource r
= message
.Resources
[id
];
207 if (r
.ContentStream
!= null)
209 htmlView
.LinkedResources
.Add(r
);
212 mailMessage
.AlternateViews
.Add(htmlView
);
219 /// Gets or sets the domain.
221 /// <value>The domain.</value>
224 get { return credentials.Domain; }
225 set { credentials.Domain = value; }
229 /// Gets or sets the name of the user.
231 /// <value>The name of the user.</value>
232 public String UserName
234 get { return credentials.UserName; }
235 set { credentials.UserName = value; }
239 /// Gets or sets the password.
241 /// <value>The password.</value>
242 public String Password
244 get { return credentials.Password; }
245 set { credentials.Password = value; }
249 /// Configures the message or the sender
250 /// with port information and eventual credential
253 /// <param name="message">Message instance</param>
254 private void ConfigureSender(Message message
)
260 smtpClient
.Credentials
= credentials
;
263 smtpClient
.Port
= port
;
270 /// Gets a value indicating whether credentials were informed.
273 /// <see langword="true"/> if this instance has credentials; otherwise, <see langword="false"/>.
275 private bool HasCredentials
277 get { return credentials.UserName != null && credentials.Password != null ? true : false; }