[说明]
我需要创建一个类来通过提供程序发送电子邮件(目前是SendGrid或Mandrill)。
目前,该项目在电子邮件核心"和#34;提供商核心",并且已经创建了这些接口:
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; }
}
然后,我创建了一个对象&#34; Email&#34;汇编具有其所有特征的电子邮件:
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
}
最后,我是一个创建&#34;提供商&#34;对象,它将使用&#34;电子邮件&#34;对象然后传递它:
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
}
[问题]
在&#34; ProviderSendGrid&#34;在&#34;发送&#34;方法,当我试图获得&#34;收件人&#34;属性,我收到以下错误:
其他信息:无法转换类型为#System; Colol.Generic.List
的对象1[Email.Core.Contact]' to type 'System.Collections.Generic.ICollection
1 [Email.Core.Interfaces.IContact]&#39;。
如果&#34; Email.Recipients&#34; property返回&#34; List&#34;。 List实现ICollection和Contact实现IContact。
我不确定我的解释是否足够明确,但如果我没有,请告诉我。
感谢您的关注。 最好的问候!
答案 0 :(得分:1)
在ProviderSendGrid类中,FormatedContacts方法应该采用 IColtact的ICollection 而不是联系
private List<string> FormatedContacts(ICollection<IContact> Recipients)
另请查看电子邮件类。对于_recipients,它有一个ICollection of Contact。
private readonly ICollection<IContact> _recipients = new List<IContact>();
最后,在添加收件人时删除Cast to Contact。
#region Public Methods
public Email AddRecipient(IContact Recipient)
{
_recipients.Add(Recipient);
return this;
}
答案 1 :(得分:0)
观察以下行:_message.AddTo(FormatedContacts(Email.Recipients))
IEmail.Recipients代码行:ICollection<IContact> Recipients { get; }
来自功能定义:private List<string> FormatedContacts(ICollection<Contact> Recipients)
函数需要ICollection<Contact>
,您要发送ICollection<IContact>