1.1.简介
1.1 简介
我们决定为任何想在Dropbox、Exchange或其他系统之间开发集成解决方案的C#开发人员写一篇简短的博客。我们创建了一个简短的应用程序示例,作为演示如何简单地完成这样的集成,可以使用 Connect Bridge 台。
1.2 前提条件
您可以扫描文章了解Connect Bridge平台的概念。此外,我们还根据要求提供了软件的免费试用授权,如果你想自己玩的话。
2.情景要求
这里要求的整合方案是 从您的Exchange电子邮件附件创建一个备份到您的Dropbox文件夹。 可能是有用的,有一个备份,或保持你的交换使用量最小或一些其他原因。
3.基本工作流程
无论你需要实施的是什么集成方案,都有基本的简单易行的3个步骤需要你去执行。接下来将介绍这些步骤。
3.1 配置CB查询分析器
第一步,是确保你能够连接到目标系统(在我们的情况下,Exchange和Dropbox);最简单的方法是通过CB查询分析器。在这里,我已经通过管理工具配置了我的ConnectBridge服务器,通过创建所需的组和用户来连接到MS Exchange 365和我的Dropbox。我创建了一个名为""的用户名马丁"与密码"1234”.该用户拥有连接Exchange365和Dropbox的权限。现在从查询分析器中,我将为每个目标系统创建2个连接,并确保能够成功连接。
图1:账户管理
图2:组和用户管理
图3.查询分析器的连接查询分析器的连接
3.2 检验你的陈述
如上图所示,我们已经成功配置并连接到两个目标系统。现在我们可以测试我们的语句了。
3.2.1.从Exchange下载附件
在我的交换账户上,我有几封邮件,只有3封邮件有附件,如下图所示。
图4:Exchange电子邮件
要从Exchange下载附件,我们需要遵循3个步骤。
1.获取带附件的邮件ID列表。
执行下面的语句应该会得到3个ID,因为我们只有3封带附件的邮件,如上图4所示。为了测试,我将取有2个附件的邮件的ID,并在下一步得到其邮件附件的列表。
SELECT ID FROM Message WHERE HasAttachment = true。
下图5为执行上述语句的输出。
2.从每封邮件中获取附件列表。
执行下面的语句,应该会得到2行,一行是readme.txt,一行是logo.jpg,如上图4所示。每个附件都会有一个名为地址的字段,在下一步下载附件时将会用到这个字段。
EXEC SP_SELECT_ATTACHMENTS 'AAMkADljZGY4ZjYzLWY2MDUtN............'。
下图6显示了执行上述语句的输出。
3.获取附件。
现在,我将下载logo.jpg附件,使用上一步得到的地址。
EXEC SP_SAVE_ATTACHMENT 'AAMkADljZGY4ZjYzLWY2MDUtNDBjOC0.......'。
下图7是执行上述语句的输出。
注:我们使用了Exchange连接器提供的一个表和两个存储过程,关于连接器提供的表和存储过程的更多信息,请参考"Exchange连接器参考"文件。
图5:获取带附件的邮件ID列表
图6:从邮件中获取附件列表
图7:获取附件
3.2.2上传文件到Dropbox中
这是一个直接的步骤。要上传一个文件到Dropbox,我们将执行一个存储过程 "SP_UPLOADFILE",该存储过程调用Dropbox上所需的API来上传文件。为了简单起见,我们将上传一个文本文件。
SP_UPLOADFILE。
EXEC SP_UPLOADFILE '@path', '@filename', '@content';
上面的存储过程期望文件的内容以字节为单位。
我想上传一个名为""的文本文件。first.txt"到Dropbox的根目录。文件的内容,将是 "Hello World";按照约定,我们需要通过自己的代码或任何在线转换器将该消息 "Hello World "转换为字节。
EXEC SP_UPLOADFILE '/', 'first.txt', 'SGVsbG8gV29ybGQ=';
注意:有关Dropbox连接器提供的表和存储过程的更多信息,请参考" "。Dropbox连接器参考"文件。
下图8和图9显示了上述存储过程的执行和输出。
图8:向Dropbox上传文件
图9:上传的文件
3.3 复制连接和声明
现在我们知道,我们能够从Exchange下载附件,我们也知道我们可以将文档上传到Dropbox。我们还测试了我们的SQL语句。现在我们需要做的是将查询分析器中的连接字符串和我们测试过的语句复制到C#应用程序中。
要从查询分析器中复制连接,我们只需要右键点击该连接,点击编辑并进入高级选项卡,从那里复制文本,如下图10所示。
图10:从查询分析器复制连接字符串
以下是我对两个目标系统的连接字符串。
Exchange
Driver={Media Gateway ODBC Driver};impl='CORBA';host='localhost';port='8087';acc='ACC_EXCH365_CU7';uid='martin';pwd='1234'
Dropbox
Driver={Media Gateway ODBC Driver};IMPL=CORBA;HOST='localhost';PORT='8087';ACC='ACC_DRBX_CBD';UID='martin';PWD='1234'
现在我们准备打开visual studio.net,开始实现我们的C#集成解决方案。
4.解决方案演练
4.1 创建一个新的C#应用程序
创建一个简单的控制台应用程序即可。我们的解决方案不需要任何外部引用或任何第三方包部署。该解决方案是基于ODBC的,因此,我们只需要将所需的命名空间导入到我们的类中。
使用System.Data.Odbc;。 使用System.Data.Odbc。
4.2 创建并打开一个与Exchange的连接
1.指定连接字符串
string connectionString = "Driver={Media Gateway ODBC Driver};IMPL=CORBA;HOST='localhost';PORT='8087';ACC='ACC_EXCH365_CU7';UID='martin';PWD='1234'"。
2.创建并打开连接:
使用 (OdbcConnection connection = new OdbcConnection(connectionString)) { connection.Open()。 ………………………… }
4.3 从Exchange下载附件
1.将Exchange邮件中带有附件的ID下载到一个DataTable "messageIDs "中,我们要用一个DataAdapter "messageAdapter "来连接和下载这些ID。
使用(OdbcDataAdapter messagesAdapter = new OdbcDataAdapter("SELECT ID FROM Message where HasAttachment = true;", connection)) { messagesAdapter.Fill(messageIDs)。 }
2.对于 "messageIDs "表中的每个电子邮件ID,我们将得到一个 "仅信息 "的附件列表,并将它们保存到另一个DataTable "documentsListTable "中。我们将使用另一个DataAdapter "documentsListAdapter "来获取该附件列表。
foreach (DataRow messageIDRow in messageIDs.Rows) { string sqlQueryString = string.Format("EXEC SP_SELECT_ATTACHMENTS '{0}';", messageIDRow["ID"])。) 使用(OdbcDataAdapter documentsListAdapter = new OdbcDataAdapter (sqlQueryString, connection)) documentsListAdapter.Fill(documentListTable)。 }
3.对于 "documentsListTable "中的每个附件,我们将得到地址,并使用它来获取实际的附件,然后将该附件添加到第三个表 "documentsTable "中。我们将使用另一个DataAdapter "documentsAdapter "来获取附件/文档。
foreach (DataRow documentInfoRow in documentsListTable.Rows) { string sqlQueryString = string.Format("EXEC SP_SAVE_ATTACHMENT '{0}';", documentInfoRow["Address"])。 使用 (documentAdapter = new OdbcDataAdapter(sqlQueryString, connection)) documentsAdapter.Fill(documentTable)。 }
4.每从交换中心成功下载一个附件,就用附件文件名向用户显示一条信息。
foreach (DataRow documentRow in documentsTable.Rows) Console.WriteLine(string.Format("{0}下载!"。 documentRow["OutFileName"]))。
4.4 关闭与Exchange的连接。
if (connection.State == ConnectionState.Open) connection.Close()。
4.5 创建并打开一个与Dropbox的连接
1.指定连接字符串
string connectionString = "Driver={Media Gateway ODBC Driver};IMPL=CORBA;HOST='localhost';PORT='8087';ACC='ACC_DRBX_CBD';UID='martin';PWD='1234'"。
2.创建并打开连接:
使用 (OdbcConnection connection = new OdbcConnection(connectionString)) { connection.Open()。 ………………………… }
4.6 将附件上传到Dropbox中。
对于每个附件文件在"文件表",我们将得到文件名为"OutFileName"和文件内容"OutBuffer"并将文件保存到Dropbox文件夹"/"的根部。
我们不需要一个新的DataAdapter,我们只需要一个基于OdbcCommand的"SP_UPLOADFILE"存储过程前面已经讨论过了,我们需要向它添加所需的参数,这样我们就可以将所需的值传递给存储过程。
foreach (DataRow documentRow in documentsTable.Rows) { using (OdbcCommand command = new OdbcCommand("Exec SP_UploadFile ? , ? , ? ", connection)) { command.CommandType = CommandType.StoredProcedure; command.Parameters.AddWithValue("@path", "/")。 command.Parameters.AddWithValue("@filename", documentRow["OutFileName"])。 command.Parameters.AddWithValue("@content", documentRow["OutBuffer"])。 fileUploadStatus = (command.ExecuteNonQuery() > 0) ?"上传了!": "未上传!"。 Console.WriteLine("{0} : {1}", documentRow["OutFileName"], fileUploadStatus)。 } }
4.7 关闭与Dropbox的连接
if (connection.State == ConnectionState.Open) connection.Close()。
5.运行解决方案
图11:运行解决方案
图12:运行解决方案后的Dropbox内容
6.6. 关于解决办法的说明
我们试图让应用逻辑尽可能的简单,然而逻辑可以通过将每个交换邮件中的附件保存到一个单独的文件夹中来改进,文件夹名称可以是邮件ID的一部分或任何其他独特的标识符。
为了简单起见,我们忽略了许多基本的编码标准,包括但不限于:
1.在配置文件中拥有连接字符串
2.使用散列码和盐对密码进行哈希和加密。
3.实现设计模式,如单一责任原则,甚至更好的是依赖反转原则。
7.完整的源代码
使用System.Data using System.Data; using System.Data.Odbc.Default 命名空间MySolution { 类别 { static void Main(string[] args) { //提供连接 string connectionString = string.Empty; string sqlQueryString = string.Empty; OdbcConnection连接。 OdbcCommand命令。 DataTable documentsTable = new DataTable(); OdbcDataAdapter messagesAdapter, documentsListAdapter, documentsAdapter; DataTable messageIDs = new DataTable(); DataTable documentsListTable = new DataTable(); //创建与Exchange的连接 connectionString = "Driver={Media Gateway ODBC Driver};IMPL=CORBA;HOST='localhost';PORT='8087';ACC='ACC_EXCH365_CU7';UID='martin';PWD='1234'" 。 using (connection = new OdbcConnection(connectionString)) { //打开连接 connection.Open(); //为带有附件的消息加载消息ID using (magesAdapter = new OdbcDataAdapter("SELECT ID FROM Message where HasAttachment = true;", connection)) { //用消息填充messageIDs表 messagesAdapter.Fill(messageIDs); } //对于每个使用消息ID的消息,获得附件的列表 foreach (DataRow messageIDRow in messageIDs.Rows) { sqlQueryString = string.Format("EXEC SP_SELECT_ATTACHMENTS '{0}';", messageIDRow["ID"); using (documentListAdapter = new OdbcDataAdapter(sqlQueryString, connection)) documentsListAdapter.Fill(documentListTable)。 } //获取每个附件并将其保存到 documentsTable 中 foreach (DataRow documentInfoRow in documentsListTable.Rows) { sqlQueryString = string.Format("EXEC SP_SAVE_ATTACHMENT '{0}';", documentInfoRow["地址"])。 using (documentAdapter = new OdbcDataAdapter(sqlQueryString, connection)) documentsAdapter.Fill(documentTable); } //向用户反馈这些文件被下载了 foreach (DataRow documentRow in documentsTable.Rows) Console.WriteLine(string.Format("{0} downloaded!", documentRow["OutFileName"]))。 //关闭与Exchange的连接 如果(connection.State == ConnectionState.Open) connection.Close()。 } //创建与DropBox的连接 connectionString = "Driver={Media Gateway ODBC Driver};IMPL=CORBA;HOST='localhost';PORT='8087';ACC='ACC_DRBX_CBD';UID='martin';PWD='1234'" 。 using (connection = new OdbcConnection(connectionString)) { //打开连接 connection.Open(); //文件上传状态占位符 string fileUploadStatus = string.Empty; //对于我们的 documentsTable 中的每个文档 foreach (DataRow documentRow in documentsTable.Rows) { //调用一个存储过程来上传文件 using (command = new OdbcCommand("Exec SP_UploadFile ? , ? , ?", connection)) { command.CommandType = CommandType.StoredProcedure; command.Parameters.AddWithValue("@path", "/")。 command.Parameters.AddWithValue("@filename", documentRow["OutFileName"])。 command.Parameters.AddWithValue("@content", documentRow["OutBuffer"])。 //检查状态并显示在屏幕上 fileUploadStatus = (command.ExecuteNonQuery() > 0) ?"Uploaded!": "未上传!"。 Console.WriteLine("{0} : {1}", documentRow["OutFileName"], fileUploadStatus) 。 } } //关闭与Dropbox的连接 如果(connection.State == ConnectionState.Open) connection.Close()。 } //向用户提供反馈 Console.WriteLine("全部完成...")。 Console.ReadKey()。 } } }