最新消息:ww12345678 的部落格重装上线,希望大家继续支持。

Ax utility function for sending mail via SMTP

网络文摘 William 1585浏览 0评论
The following is a quick utility function that can be used to send an email via a configured SMTP server. See comment in the code for the structure of the 'attachments' parameter. This was adapted from another code-sample, and should work with version 2009 and later.

Note this sends the mail immediately via a direct connection to the SMTP server. The preferred approach should be to create an entry in the SysOutgoingEmailTable (and SysOutgoingEmailData if attachments are required). Entries in that table are periodically scanned by the email distributor process (SysEmailDistributor), and will correctly handle errors/retries etc. See second code sample further down the post.


static public void sendMail(
str fromAddress, // NB single address only
str toAddress, // " "
str ccAddress, // " "
str subject,
str body,
container attachments = conNull())
{

// Send mail via SMTP
// Attachments is a container of format:
// [ Source file 1, Attachment name 1, Source file 2, Attachment name 2, ... ]

SysEmailParameters emailParams = SysEmailParameters::find();

System.Net.Mail.MailMessage message;
System.Net.Mail.Attachment attachment;
System.Net.Mail.AttachmentCollection attachementCollection;
System.Net.Mail.SmtpClient mailClient;
System.Net.Mail.MailAddressCollection addressCollection;
str mailServer;
int mailServerPort;
str attachmentFilename;
str attachmentName;
int idx;

System.Exception clrException;
InteropPermission perm;
;

if(!fromAddress)
throw error("From address has not been specified");
if(!toAddress)
throw error("To address has not been specified");

try
{
perm = new InteropPermission(InteropKind::ClrInterop);
perm.assert();

mailServer = emailParams.SMTPRelayServerName;
mailServerPort = emailParams.SMTPPortNumber;

if(!mailServerPort)
mailServerPort = 25; // default SMTP port

message = new System.Net.Mail.MailMessage(
new System.Net.Mail.MailAddress(fromAddress,''),
new System.Net.Mail.MailAddress(toAddress,''));

addressCollection = message.get_CC();
if(ccAddress)
addressCollection.Add(ccAddress);

message.set_Subject(subject);

message.set_Body(body);
attachementCollection = message.get_Attachments();

if((conlen(attachments) mod 2) != 0)
throw error(error::wrongUseOfFunction(funcName()));

for(idx = 1;idx <= conLen(attachments);idx += 2)
{
attachmentFilename = conPeek(attachments,idx);
attachmentName = conpeek(attachments,idx + 1);

attachment = new System.Net.Mail.Attachment(attachmentFilename);
attachment.set_Name(attachmentName);
attachementCollection.Add(attachment);
}

mailClient = new System.Net.Mail.SmtpClient(mailServer,mailServerPort);
mailClient.Send(message);

}
catch(Exception::CLRError)
{
clrException = CLRInterop::getLastException();
error(clrException.get_Message());
if(clrException.get_InnerException() != null)
{
clrException = clrException.get_InnerException();
error(clrException.get_Message());
}
throw Exception::Error;
}

}

And to test it out (assuming the method has been added to a new class called MailHelper):
MailHelper::sendMail(
'admin@bigbusiness.com',
'client@gmail.com',
'linemanager@bigbusiness.com',
'Congratulations!!',
'You have just won an email.');

A note for developers - A handy tool for testing mailers or email-related processes can be downloaded at http://smtp4dev.codeplex.com/. It allows you to run a light-weight SMTP server locally for development and testing, and is definitely worth a look.

The following function can be used to send mail via inserting into the outgoing mail queue, utilizing the template functionality in Ax. This is a slightly modified/cleaned-up version of the method sendMail in table SysEmailTable. If specific mappings are required, pass a map<string,string> that contains token names and values. These can then be referenced in the template using the format %TOKENNAME%.

server static void insertMailToQueue(
SysEmailId _emailId,
LanguageId _language,
str _emailAddr,
Map _mappings = null,
container attachments = conNull())
{
// Adapted from SysEmailTable::sendMail

#SysMailer
LanguageId languageId;

SysEmailTable table = SysEmailTable::find(_emailId);
SysEmailMessageTable message;

str messageBody;
container data;
container embeddedBinaryData;

Filename filePath;
Filename filename;
Filename fileExtension;

List list;
ListEnumerator enumerator;
Filename htmlDecodedFileName;

int i = 1;
int maxAttachmentSize;

BinData binData;

SysOutgoingEmailTable outgoingEmailTable;
SysOutgoingEmailData outgoingEmailData;

SysEmailBatch batch = SysEmailBatch::construct();
FileIOPermission fileIOPermission;

SysEmailParameters emailParams = SysEmailParameters::find();
str attachFilename;
str attachAttachmentName;
int attachmentIDx;

;

maxAttachmentSize = emailParams.MaxEmailAttachmentSize;

//maxAttachmentSize in megabytes
if (maxAttachmentSize < 1)
maxAttachmentSize = #maxAttachmentSizeDefault;

if (_language)
languageId = _language;
else
languageId = table.DefaultLanguage;

message = SysEmailMessageTable::find(_emailId, languageId);

if (!message)
message = SysEmailMessageTable::find(_emailId, table.DefaultLanguage);

if (!message)
throw error(strFmt("@SYS74260", _language));

if (message.LayoutType == SysEmailLayoutType::StaticLayout)
messageBody = message.Mail;
else
throw error(strFmt("Layout type '%1' in email %2 is not supported by this function",
message.LayoutType,
message.EmailId));

messageBody = SysLabel::resolveLabels(messageBody, languageId);

ttsbegin;

outgoingEmailTable.EmailItemId = EventInbox::nextEventId();
outgoingEmailTable.TemplateId = table.EmailId;
outgoingEmailTable.IsSystemEmail = NoYes::No;
outgoingEmailTable.Sender = table.SenderAddr;
outgoingEmailTable.SenderName = table.SenderName;
outgoingEmailTable.Recipient = _emailAddr;

//note: first do the xml transform if needed, params are substitued after that
messageBody = SysEmailMessage::stringExpand(messageBody, SysEmailTable::htmlEncodeParameters(_mappings));
messageBody = strReplace(messageBody, 'n', '<br>');
[outgoingEmailTable.Message, data] = SysEmailTable::embedImages(messageBody);

list = List::create(data);
enumerator = list.getEnumerator();
while (enumerator.moveNext())
{
htmlDecodedFileName = SysEmailTable::htmlDecode(enumerator.current());

fileIOPermission = new FileIOPermission(htmlDecodedFileName,'r');
fileIOPermission.assert();
//BP Deviation Documented
if (WinAPIServer::fileExists(htmlDecodedFileName) &&
//BP Deviation Documented
(WinAPIServer::fileSize( htmlDecodedFileName) < (maxAttachmentSize * 1000000)) &&
SysEmailTable::isFromAttachmentsFolder(htmlDecodedFileName))
{
binData = new BinData();
//BP Deviation Documented
binData.loadFile(htmlDecodedFileName);
embeddedBinaryData = binData.getData();

outgoingEmailData.EmailItemId = outgoingEmailTable.EmailItemId;
outgoingEmailData.DataId = i;
outgoingEmailData.EmailDataType = SysEmailDataType::Embedded;
outgoingEmailData.Data = embeddedBinaryData;
[filePath, filename, fileExtension] = Global::fileNameSplit(htmlDecodedFileName);

outgoingEmailData.FileName = int642str(outgoingEmailTable.EmailItemId) + '_' + int2str(i);
outgoingEmailData.FileExtension = fileExtension;

outgoingEmailData.insert();

i++;
}

CodeAccessPermission::revertAssert();
}

outgoingEmailTable.Subject = SysEmailMessage::stringExpand(message.Subject, _mappings);

outgoingEmailTable.Priority = table.Priority;
outgoingEmailTable.WithRetries = false;
outgoingEmailTable.RetryNum = 0;
outgoingEmailTable.UserId = curUserId();
outgoingEmailTable.Status = SysEmailStatus::Unsent;

for(attachmentIDx = 1;attachmentIDx <= conLen(attachments);attachmentIDx += 2)
{
attachFilename = conPeek(attachments,attachmentIDx);
attachAttachmentName = conPeek(attachments,attachmentIDx + 1);

fileIOPermission = new FileIOPermission(attachFilename,'r');
fileIOPermission.assert();

if (attachFilename && WinAPIServer::fileExists(attachFilename))
{
if (WinAPIServer::fileSize(attachFilename) < (maxAttachmentSize * 1000000))
{
binData = new BinData();
binData.loadFile(attachFilename);
embeddedBinaryData = binData.getData();

outgoingEmailData.EmailItemId = outgoingEmailTable.EmailItemId;
outgoingEmailData.DataId = i;
outgoingEmailData.EmailDataType = SysEmailDataType::Attachment;
outgoingEmailData.Data = embeddedBinaryData;
[filePath, filename, fileExtension] = Global::fileNameSplit(attachFilename);
outgoingEmailData.FileName = attachAttachmentName;
outgoingEmailData.FileExtension = fileExtension;

outgoingEmailData.insert();
}
}
}

CodeAccessPermission::revertAssert();

outgoingEmailTable.LatestStatusChangeDateTime = DateTimeUtil::getSystemDateTime();
outgoingEmailTable.insert();

ttscommit;
}

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址