[解释]
我需要创建一个类以通过提供程序(现在是SendGrid或Mandrill)发送电子邮件。
现在,将项目划分为“电子邮件核心”和“提供者核心”,并且已经创建了这些接口:
public interface IEmail
{
ICollection<IContact> Recipients { get; }
IContact From { get; set; }
string EmailBody { get; set; }
string Subject { get; set; }
IContact ReplyTo { get; set; }
ICollection<IContact> Attachments { get; }
}
这是依赖
public interface IContact
{
string Name { get; set; }
string Email { get; set; }
}
public interface IAttachment
{
string FileName { get; set; }
Stream Content { get; set; }
string StringContent { get; }
string ContentType { get; set; }
string FilePath { get; set; }
}
然后,我创建了一个对象“ Email”来组装具有所有特征的电子邮件:
public class Email : IEmail
{
#region Constructors
public Email()
{
}
#endregion
#region Private Properties
private readonly ICollection<Contact> _recipients = new List<Contact>();
private readonly ICollection<Attachment> _attachments = new List<Attachment>();
#endregion
#region Public Properties
public ICollection<IContact> Recipients
{
get
{
return (ICollection<IContact>)_recipients;
}
}
public IContact From
{
get;
set;
}
public string EmailBody
{
get;
set;
}
public string Subject
{
get;
set;
}
public IContact ReplyTo
{
get;
set;
}
public ICollection<IAttachment> Attachments
{
get { return (ICollection<IAttachment>)_attachments ;}
}
#endregion
#region Private Methods
#endregion
#region Public Methods
public Email AddRecipient(IContact Recipient)
{
_recipients.Add((Contact)Recipient);
return this;
}
public Email SetFrom(IContact from)
{
From = from;
return this;
}
public Email SetEmailBody(string body)
{
EmailBody = body;
return this;
}
public Email SetSubject(string subject)
{
Subject = subject;
return this;
}
public Email SetReplyTo(IContact replyto)
{
ReplyTo = replyto;
return this;
}
public Email AddAttachment(IAttachment attachment)
{
_attachments.Add((Attachment)attachment);
return this;
}
#endregion
}
最后,我有一个类来创建“ Provider”对象,该对象将使用“ Email”对象,然后将其传递:
public class ProviderSendGrid : IProvider
{
#region Constructors
public ProviderSendGrid(string SendGridUser, string SendGridPassword)
{
_networdcredential = new NetworkCredential(SendGridUser, SendGridPassword);
_sendgridweb = new Web(_networdcredential);
}
#endregion
#region Propriedades Privadas
private NetworkCredential _networdcredential;
private SendGridMessage _message;
private Web _sendgridweb;
#endregion
#region Public Properties
#endregion
#region Private Methods
/// <summary>
/// Verifica se string é e-mail
/// </summary>
/// <param name="Email">String que se deseja verificar se é e-mail ou não.</param>
/// <returns>Retorna verdadeiro caso a string informada seja um e-mail e falso caso contrário.</returns>
private bool IsValidEmail(string Email)
{
try
{
var address = new MailAddress(Email);
return address.Address == Email;
}
catch
{
return false;
}
}
private List<string> FormatedContacts(ICollection<IContact> Recipients)
{
if (Recipients == null)
throw new Exception("Recipients parameter on Recipients method can't be null.");
List<string> lstRet = new List<string>();
Parallel.ForEach(Recipients, item =>
{
if (!IsValidEmail(item.Email))
throw new Exception("Invalid e-mail informed.", new Exception("The following e-mail is not valid: " + item.Email));
lstRet.Add(item.Name + " <" + item.Email + ">");
});
return lstRet;
}
#endregion
#region Public Methods
/// <summary>
///
/// </summary>
/// <param name="Email">Objeto que implemente a interface MKM.Email.Core.Interfaces.IEmail</param>
public async void Send(IEmail Email)
{
if (string.IsNullOrEmpty(Email.EmailBody) || string.IsNullOrEmpty(Email.Subject))
throw new Exception("Email body or subject is null.");
if (Email.From == null)
throw new Exception(@"The property ""From"" can't be null.");
//Compondo a mensagem
_message = new SendGridMessage();
//Stackoverflow Forum: The error occours in the following line, when I try to get the "Recipients" property from "Email" object
_message.AddTo(FormatedContacts(Email.Recipients));
_message.From = new MailAddress(Email.From.Email, Email.From.Name);
_message.Subject = Email.Subject;
_message.Html = Email.EmailBody;
Parallel.ForEach(Email.Attachments, item =>
{
_message.AddAttachment(item.Content, item.FileName);
});
_message.ReplyTo = new MailAddress[]{new MailAddress(Email.ReplyTo.Email, Email.ReplyTo.Name)};
await _sendgridweb.DeliverAsync(_message);
}
#endregion
}
[问题]
在“ ProviderSendGrid”类的“发送”方法中,当我尝试获取“收件人”属性时,收到以下错误:
附加信息:无法转换类型为'System.Collections.Generic.List
1[Email.Core.Contact]' to type 'System.Collections.Generic.ICollection
1 [Email.Core.Interfaces.IContact]'的对象。
如果“ Email.Recipients”属性返回“列表”,为什么会发生这种情况。列表实现ICollection,而联系人实现IContact。
我不确定我的解释是否足够清楚,但是如果我不明白,请告诉我。
感谢您的关注。最好的祝福!
在ProviderSendGrid类中,FormatedContacts方法应采用IContact的ICollection而不是Contact
private List<string> FormatedContacts(ICollection<IContact> Recipients)
还要检查电子邮件类别。它具有_recipients的Contact的ICollection。
private readonly ICollection<IContact> _recipients = new List<IContact>();
最后,在添加收件人时删除“投射到联系人”。
#region Public Methods
public Email AddRecipient(IContact Recipient)
{
_recipients.Add(Recipient);
return this;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句