1.1.简介
1.1 简介
我们决定为任何想在Dropbox、Exchange或其他系统之间开发集成解决方案的C#开发人员写一篇简短的博客。我们创建了一个简短的应用程序示例,作为演示如何简单地完成这样的集成,可以使用 Connect Bridge 台。
1.2 前提条件
您可以扫描文章了解Connect Bridge平台的概念。此外,我们还根据要求提供了软件的免费试用授权,如果你想自己玩的话。
2.情景要求
这里要求的整合方案是 从您的Exchange电子邮件附件创建一个备份到您的Dropbox文件夹。 可能是有用的,有一个备份,或保持你的交换使用量最小或一些其他原因。
3.基本工作流程
无论你需要实施的是什么集成方案,都有基本的简单易行的3个步骤需要你去执行。接下来将介绍这些步骤。
3.1 配置CB查询分析器
第一步,是确保能够连接到目标系统(本场景中为Exchange和Dropbox);最简便的方式是通过ConnectBridge查询分析器实现。在此之前,我已通过管理工具配置好ConnectBridge服务器,使其能够连接到MS Exchange 365及我的Dropbox账户,并创建了所需的组和用户。我创建了一个名为“马丁”,密码为“1234”该用户拥有连接至Exchange365和Dropbox的权限。现在我将通过查询分析器为每个目标系统创建两个连接,并确保能够成功连接。.

图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附件,使用上一步得到的地址。
执行存储过程 SP_SAVE_ATTACHMENT 'AAMkADljZGY4ZjYzLWY2MDUtNDBjOC0…….';
下图7是执行上述语句的输出。
注:我们使用了Exchange连接器提供的表和2个存储过程,有关连接器提供的表和存储过程的更多信息,请参阅“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.创建&打开连接。
using (OdbcConnection connection = new OdbcConnection(connectionString)) { connection.Open();…………………………}
4.3 从Exchange下载附件
1. 将Exchange邮箱中带附件的邮件ID下载到名为“messageIDs”的数据表中。我们将使用名为“messagesAdapter”的数据适配器进行连接并下载这些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”中。我们将使用另一个数据适配器“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.创建&打开连接。
using (OdbcConnection connection = new OdbcConnection(connectionString)) { connection.Open();…………………………}
4.6 将附件上传到Dropbox中。
对于“文件表”,我们将得到文件名“OutFileName”以及文件内容“OutBuffer”并将文件保存至Dropbox文件夹根目录“/”。.
我们不需要新的DataAdapter,只需基于“SP_UPLOADFILE”我们需要为之前讨论的存储过程添加所需参数,以便能够向该存储过程传递所需的值。.
foreach (DataRow documentRow in documentsTable.Rows)
{
using (OdbcCommand command = new OdbcCommand("Exec SP_UploadFile ?, ?, ?",
连接))
{
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!":
"Not Uploaded!";
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.Odbc;。
使用System.Data.Odbc。
命名空间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。
使用(MessagesAdapter = new OdbcDataAdapter("SELECT ID FROM Message where HasAttachment = true;", connection))
{
//用消息填充消息IDs表
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["Address"])。
using (documentAdapter = new OdbcDataAdapter(sqlQueryString, connection))
documentsAdapter.Fill(documentTable)。
}
//给用户反馈这些文件被下载了。
foreach (DataRow documentRow in documentsTable.Rows)
Console.WriteLine(string.Format("{0}下载!", documentRow["OutFileName"]))。
//关闭与Exchange的连接
if (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;
//对于我们在文档表中的每一个文档
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!" : "Not Uploaded!"; ?: "Not Uploaded!";
Console.WriteLine("{0} : {1}", documentRow["OutFileName"], fileUploadStatus);
}
}
//关闭与Dropbox的连接
if (connection.State == ConnectionState.Open)
connection.Close();
}
//向用户提供反馈
Console.WriteLine("all done...")。
Console.ReadKey();
}
}
}
