65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 C# 发送 Lotus Notes 电子邮件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.30/5 (7投票s)

2008年9月17日

CPOL

4分钟阅读

viewsIcon

129287

如何使用 C# 发送邮件至 Lotus Notes。

LotusNotesWithCS/AddUsingStatement.jpg

引言

我在工作中遇到了这个问题;我需要通过 Lotus Notes 电子邮件发送一个通知,其中包含错误的描述(ex.Message)以及导致错误的文件的名称。例如:在数据库中查找 XML 文件中未提供的、用于创建管道分隔的平面文件的值。这会导致平面文件处理失败;它会被移到一个错误文件夹,并创建一个事件日志条目。当然,这对用户没有帮助,但电子邮件可以。互联网上关于 C# 到 Lotus Notes 的信息不多,所以我参考了一些 VBA 示例和一些 C# GUI 示例,并根据我的需要进行了修改,因为现有的方法不适用于 Windows 服务。这样,服务就可以使用应用程序,最重要的是,我只需要查看我的电子邮件即可。

我还使用此过程创建电子邮件,通知另一位用户文件已成功处理,正在等待他们导入 ERP 系统。

背景

此功能的作用

  1. 在 Windows 服务中自动处理电子邮件流程。
  2. 在主题行中为用户提供简要描述。例如:账单错误:文件未处理
  3. 在电子邮件正文中,它会向用户提供文件名、易于理解的错误信息以及解决问题的有用提示。例如,我们的一些工单没有指定主要技术人员;这个值会在数据库中查找,并且不包含在 XML 文件中。缺少主要技术人员会导致抛出错误(我为此创建了几个自定义异常,例如:LeadTechNotFoundException)。我用它来告诉用户去数据库添加主要技术人员,然后将 XML 文件从错误文件夹移回处理文件夹。服务会通过 FileSystemWatchers 监视并重新处理它。如果他们复制而不是移动,我会检查文件是否存在并删除它。简单吧?

使用代码

设置对 Domino COM 对象的引用。

LotusNotesWithCS/DominoAddRef.jpg

此代码可按原样使用或修改。它是完全可用的(至少在我的系统上)。

static void SendNotesErrorMail( string err, string file) 
{
    //Pass in file name 
    string filename = file; 
    //Pass in error message from TryCatch 
    string errMessage = err; 
    //Create new notes session 
    NotesSession _notesSession = new NotesSession(); 
    //Initialize Notes Database to null; nothing in VB. 
    NotesDatabase _notesDataBase = null; 
    //Initialize Notes Document to null; nothing in VB. 
    NotesDocument _notesDocument = null; 
    //Notes Server Name in form of: ServerName/Domain. 
    string sServerName = ConfigurationManager.AppSettings [ "ServerName" ]; 

    //Mail File is in form of: mail\\userName.nsf 
    string sMailFile = ConfigurationManager.AppSettings [ "MailFile" ]; 
    string password = ConfigurationManager.AppSettings [ "Password" ]; 
    string sSendTo = ConfigurationManager.AppSettings [ "SendTo" ]; 
    string sSubject = "Billing Error"; 
    //required for send, since it's byRef and not byVal, gets set later. 
    object oItemValue = null; 
    //use string array to CC Send 
    string[] sCopyTo = new string[4]; 
    sCopyTo [ 0 ] = 
        ConfigurationManager.AppSettings [ "Recipient0" ]; 
    sCopyTo [ 1 ] = 
        ConfigurationManager.AppSettings [ "Recipient1" ]; 
    sCopyTo [ 2 ] = 
        ConfigurationManager.AppSettings [ "Recipient2" ]; 
    sCopyTo [ 3 ] = 
        ConfigurationManager.AppSettings [ "Recipient3" ]; 
    //Initialize Notes Session 
    _notesSession.Initialize(password);

    //Get Database via server name & c:\notes\data\mailfilename.nsf 
    //if not found set to false to not create one 
    _notesDataBase = _notesSession.GetDatabase(sServerName, sMailFile, 
        false); 

    //If the database is not already open then open it. 
    if ( !_notesDataBase.IsOpen ) 
    {
        _notesDataBase.Open( );
    }

    //Create the notes document 
    _notesDocument = _notesDataBase.CreateDocument();

    //Set document type 
    _notesDocument.ReplaceItemValue(
        "Form", "Memo"); 

    //sent notes memo fields (To: CC: Bcc: Subject etc) 
    _notesDocument.ReplaceItemValue(
        "SendTo", sSendTo); 
    _notesDocument.ReplaceItemValue(
        "CopyTo", sCopyTo); 
    _notesDocument.ReplaceItemValue(
        "Subject", sSubject); 

    //Set the body of the email. This allows you to use the appendtext 
    NotesRichTextItem _richTextItem = _notesDocument.CreateRichTextItem("Body"); 

    //add lines to memo email body. the \r\n is needed for each new line. 
    _richTextItem.AppendText(
        "Error: " + errMessage + "\r\n"); 
    _richTextItem.AppendText(
        "File: " + filename + "\r\n"); 
    _richTextItem.AppendText(
        "Resolution: " + resolution + "\r\n"); 
    //send email & pass in byRef field, this case SendTo (always have this, 

    //cc or bcc may not always be there. 
    oItemValue = _notesDocument.GetItemValue( 
        "SendTo" ); 
    _notesDocument.Send(
        false, ref oItemValue); 

    //release resources. 
    _richTextItem = 
        null; 
    _notesDocument = 
        null; 
    _notesDataBase = 
        null; 
    _notesSession = 
        null; 
}

关注点

这很费劲。有很多关于 VBA / Access / Excel 与 Lotus Notes 的教程等。这里还有一个来自其他用户的相当不错的示例,带有一个 GUI。

我将要做的更改是检查 app.config 文件中的一个值,并根据该计数设置数组大小。我还需要在“分辨率”部分添加一些额外的部分供我的用户使用。如果我有时间,我可能会发布一个示例项目。

这是我在这里的第一个帖子,希望它能帮助到别人。

更新

  1. 将文件错误写入 sql server 以便跟踪,捕获文件名、日期时间、错误等信息。
  2. 它为每个文件错误/成功创建并发送一封电子邮件。
  3. 它将所有电子邮件的副本发送到“主要”电子邮件地址。每条文件错误及其原因,以及发送给客户的每份报告/工单都有记录。
  4. 我将用于测试的手动流程转换为了一个 Windows 服务,该服务使用目录监视器来捕获放入文件夹的新创建的文件,并按 FIFO(先进先出)的顺序进行处理。
  5. 我将错误注释掉了,这样您就可以看到哪些是正确的,哪些不是(至少对于我的用途而言)。
  6. 我使用 Configuration.Manager.AppSettings 变量,因为停止服务、更改一行比编辑代码、重新编译、测试和部署更容易。这样您只需停止服务,更改 app.config 文件,保存然后启动服务。当网络人员更改了您的邮件服务器时,这非常有效。
  7. 在最后,有一个代码中引用的 App.Config 文件的示例,供那些不知道如何使用它的人参考。

在类的头部分添加 System.net.mail 的 using 语句。

public static void CreateSuccessMessage()
{
string mailServer = ConfigurationManager.AppSettings["ServerName"];
string SendTo = ConfigurationManager.AppSettings["BaanSendTo"];
string SendFrom = ConfigurationManager.AppSettings["SendFrom"];
MailMessage message = new MailMessage(SendFrom, SendTo);
message.Subject = "WorkOrder/Contract Import File Ready.";
message.Body = "File Ready To Process";

SmtpClient client = new SmtpClient(mailServer);
// Credentials are necessary if the server requires the client 
// to authenticate before it will send e-mail on the client's behalf.
client.UseDefaultCredentials = false;
client.Send(message);
}

public static void SendSmtpMessage(int messageType, string workContract, string err, string fileName)
{
string mailServer = ConfigurationManager.AppSettings["ServerName"];
string SendFrom = ConfigurationManager.AppSettings["SendFrom"];
MailMessage message = new MailMessage();

if (messageType == 0)
{
//send success message

//string SendTo = ConfigurationManager.AppSettings["BaanSendTo"];
//string CopyTo = ConfigurationManager.AppSettings["Recipient3"];
//message = new MailMessage(SendFrom, SendTo + "," + CopyTo);
//message.Subject = System.Environment.MachineName + ": WorkOrder/Contract Baan Import File Ready.";
//message.Body = fileName + " Is Ready To Process";
//message.Body = "Originating Server: " + System.Environment.MachineName;
//message.Body += System.Environment.NewLine;

}
else
{
//string strSQL = "INSERT INTO tblXmlOutErrors (ErrorDate, ErrorMessage, filename, Server, WorkOrderNumber) " +
// "Values (" + DateTime.Now + ", " + err + ", " + fileName + ", " + System.Environment.MachineName +", " + workContract + ")"; //ContractNumber + ", " + WorkOrderNumber + ")"

string strSQL = "pS1FxXmlOutErrors_Insert ";
strSQL = strSQL + "'" + DateTime.Now + "'," + "'" + err + "'," + "'" + fileName + "'," + "'" + System.Environment.MachineName + "'," + "'" + workContract + "'";

string sqlConnectionString = ConfigurationManager.ConnectionStrings["AppConfigConnectionNameHere"].ConnectionString;

SqlConnection db_conn = new SqlConnection(sqlConnectionString);

SqlCommand ErrorInsertSqlCommand = new SqlCommand();

Trace.WriteLine(strSQL);

ErrorInsertSqlCommand.Connection = db_conn;
ErrorInsertSqlCommand.CommandText = strSQL;
ErrorInsertSqlCommand.CommandType = CommandType.Text;

db_conn.Open();

ErrorInsertSqlCommand.ExecuteNonQuery();

db_conn.Close();

//Send error Message.
string SendTo = ConfigurationManager.AppSettings["SendTo"];
string CopyTo = ConfigurationManager.AppSettings["Recipient1"];

message = new MailMessage(SendFrom, SendTo + "," + CopyTo);
message.Subject = System.Environment.MachineName + ": WorkOrder/Contract File Error.";
message.Body = "Originating Server: " + System.Environment.MachineName;
message.Body += System.Environment.NewLine;
message.Body += "WorkOrder/Contract Number: " + workContract;
message.Body += System.Environment.NewLine;
message.Body += "File That Caused The Error: " + fileName;
message.Body += System.Environment.NewLine;
message.Body += "The Error Message is: " + err;
message.Body += System.Environment.NewLine;
message.Body += "Suggested Action: Go Into System, Correct Values, Save And Re-Export";
}

SmtpClient client = new SmtpClient(mailServer);
// Credentials are necessary if the server requires the client 
// to authenticate before it will send e-mail on the client's behalf.
client.UseDefaultCredentials = false;
client.Send(message);
}

public static void SendPdfWorkOrderCompletedEmail(string workContract, string ReportFileName, string strEmailTo, string strMailFrom)
{
string mailServer = ConfigurationManager.AppSettings["ServerName"];
string SendFrom = strMailFrom;
string SendTo = strEmailTo.Replace(";", ",");
SendTo = SendTo + ", hardcodedemainaddresshere";
string recptnts = SendTo.Replace(".com", "");
recptnts = recptnts.Replace(".net", "");
recptnts = recptnts.Replace(".org", "");
recptnts = recptnts.Replace(".biz", "");

MailMessage message = new MailMessage();
message = new MailMessage(SendFrom, SendTo);
message.Subject = "SourceOne Workorder " + workContract + " completed.";
message.Body = "To " + recptnts + ":";
message.Body += System.Environment.NewLine;
message.Body += System.Environment.NewLine;
message.Body += " Your e-mail address(es) are listed on this service event to receive an electronic copy of the Workorder.";
message.Body += System.Environment.NewLine;
message.Body += "The details of this event are included in the attached PDF file.";
message.Body += System.Environment.NewLine;
message.Body += "If you have received this e-mail in error, please reply to have your address removed from future Workorders.";
message.Body += System.Environment.NewLine;
message.Body += "Thank you for your Business.";
message.Body += System.Environment.NewLine;
message.Body += System.Environment.NewLine;

message.Attachments.Add(new Attachment(ReportFileName));

SmtpClient client = new SmtpClient(mailServer);

client.UseDefaultCredentials = false;
client.Send(message);

string strSQL = "StoredProcedureNameToUpdateCustomBoolField_pdfEmailSent ";
strSQL = strSQL + "'" + workContract + "'";

string sqlConnectionString = ConfigurationManager.ConnectionStrings["NameHere"].ConnectionString;

SqlConnection db_conn = new SqlConnection(sqlConnectionString);

SqlCommand PdfSentUpdateSqlCommand = new SqlCommand();

Trace.WriteLine(strSQL);

PdfSentUpdateSqlCommand.Connection = db_conn;
PdfSentUpdateSqlCommand.CommandText = strSQL;
PdfSentUpdateSqlCommand.CommandType = CommandType.Text;

db_conn.Open();

PdfSentUpdateSqlCommand.ExecuteNonQuery();

db_conn.Close();

//if (File.Exists(ReportFileName))
//{
// File.Replace(ReportFileName, ReportFileName,"",true);
// //File.Delete(ReportFileName);
//}
}

public static void SendSmtpBillingFileIssuesMessage()
{
string mailServer = ConfigurationManager.AppSettings["ServerName"];
string SendFrom = ConfigurationManager.AppSettings["SendFrom"];
string SendTo = ConfigurationManager.AppSettings["Recipient5"];

MailMessage message = new MailMessage(SendFrom, SendTo);
message.Subject = "Flat Files To ERP System Building Up.";
message.Body = "Check that the File Transfer Service Is Running, If Not Start It.";
message.Body += System.Environment.NewLine;
message.Body += "Service Runs Every " + ConfigurationManager.AppSettings["ElapsedTime"];
message.Body += System.Environment.NewLine;
message.Body += "Check it again after that time frame, or wait for another mail message.";

SmtpClient client = new SmtpClient(mailServer);
// Credentials are necessary if the server requires the client 
// to authenticate before it will send e-mail on the client's behalf.
client.UseDefaultCredentials = false;
client.Send(message);
}

AppConfig 示例:在第一组引号中是代码中的变量 refd,在第二组引号中是值。

<maillistadd key="FileInPath" value="C:\Folder\subFolder" />

<!-- The File Transfer Timer In Minutes-->
 <add key="ElapsedTime" value="5"/>
    <add key="ServerName" value="mail.somedomain.com"/>
    <add key="SendTo" value="CommaSeperatedInHouseErrorlist"/>
    <add key="SendFrom" value="mainemail@somedomain.com"/>
    <add key="2nd email SendTo type" value="emaillist"/>
    <add key="Recipient0" value="emaillist"/>
    <add key="Recipient1" value="maillist"/>
    <add key="Recipient2" value="maillist"/>
    <add key="Recipient3" value="maillist"/>
    <add key="Recipient4" value="maillist"/>
    <add key="Recipient5" value="maillist"/> 
    </appSettings>
    <connectionStrings>
        <add name="ConnectionVariableName" connectionString="Data Source=ServerName;Initial Catalog=databaseName;Persist Security Info=True;User ID=UserID;Password=PW;MultipleActiveResultSets=True;"/>
    </connectionStrings>

就这样。对于发送电子邮件给客户、发送错误到内部部门、发送通知到内部部门以及在数据表中记录错误和问题并进行报告,它都非常好非常好。

希望它有帮助。

祝您愉快!

© . All rights reserved.