1. Introdução
1.1 Introdução
Decidimos escrever um pequeno blog para qualquer desenvolvedor do C# que gostaria de desenvolver uma solução de integração entre sistemas como Dropbox, Exchange ou muitos outros. Criamos uma pequena aplicação que serve como demonstração de como essa integração pode ser realizada de forma simples usando o Connect Bridge plataforma.
1.2 Pré-requisitos
Você pode digitalizar o artigo para entender o conceito da plataforma Connect Bridge. Além disso, nós também fornecemos uma licença de teste gratuita do software mediante solicitação, caso você queira jogar com ele por conta própria.
2. 2. Requisitos do Cenário
O cenário de integração necessário aqui é crie uma cópia de segurança a partir dos seus e-mails de troca anexos à sua pasta Dropbox. Pode ser útil para ter um backup, ou para manter o seu uso de troca ao mínimo ou algumas outras razões.
3. Fluxo de Trabalho Básico
Não importa qual é a solução de integração que você precisa implementar, existem 3 passos básicos fáceis de seguir que você precisa executar. Esses passos são abordados a seguir.
3.1 Configurar o CB Query Analyzer
O primeiro passo é garantir que você consegue se conectar ao sistema de destino (Exchange e Dropbox no nosso cenário); a maneira mais fácil de fazer isso é através do CB Query Analyzer. Aqui, eu já configurei o meu servidor ConnectBridge através da ferramenta de administração para se conectar ao MS Exchange 365 e ao meu Dropbox, criando os grupos e utilizadores necessários. Criei um nome de utilizador chamado “martin” com a palavra-passe “1234”. Este utilizador tem direitos para se ligar ao Exchange365 e ao Dropbox. Agora, a partir do Query Analyzer, vou criar duas ligações para cada sistema de destino e garantir que consigo ligar-me com sucesso.

Figura 1: Administração de Contas

Figura 2: Administração de Grupos e Usuários

Figura 3: Conexões do Analisador de Consulta
3.2 Teste as suas declarações
Como mostrado acima, temos uma configuração e conexão bem sucedida com ambos os sistemas alvo. Agora podemos testar as nossas declarações.
3.2.1. Descarga de anexos do Exchange
Na minha conta de troca, tenho alguns e-mails, com apenas 3 e-mails que têm anexos, como mostrado abaixo
Figura 4: Exchange Emails

Para descarregar os anexos da troca, precisamos de seguir 3 passos:
1. Obter lista de IDs de e-mail com anexos:
A execução da declaração abaixo deve nos dar 3 identificações, pois temos apenas 3 e-mails com anexos, como mostrado na Figura 4 acima. Para testar vou pegar o ID do e-mail que tem 2 anexos e obter a lista dos seus anexos de e-mail na próxima etapa.
SELECT ID FROM Message WHERE HasAttachment = true;
A Figura 5 abaixo mostra o resultado da execução da declaração acima.
2. Obtenha a lista de anexos de cada e-mail:
Executando a declaração abaixo, deve nos dar 2 linhas, uma para o readme.txt e outra para o logo.jpg, como mostrado na Figura 4 acima. Cada anexo terá um campo chamado endereço que será usado no próximo passo para fazer o download do anexo
EXEC SP_SELECT_ATTACHMENTS 'AAMkADljZGY4ZjYzLWY2MDUtN…………';
A Figura 6 abaixo mostra o resultado da execução da declaração acima.
3. Vai buscar os anexos:
Agora, vou baixar o anexo logo.jpg usando seu endereço que obtive do passo anterior
EXEC SP_SAVE_ATTACHMENT 'AAMkADljZGY4ZjYzLWY2MDUtNDBjOC0…….';
A Figura 7 abaixo mostra o resultado da execução da declaração acima.
Nota: utilizámos uma tabela e dois procedimentos armazenados oferecidos pelo conector Exchange. Para obter mais informações sobre as tabelas e os procedimentos armazenados oferecidos pelo conector, consulte o “Exchange Referência do conector” documento.

Figura 5: Obter lista de IDs de e-mail com anexos

Figura 6: Obter lista de anexos a partir de um e-mail

Figura 7: Obter um anexo
3.2.2 Upload de um arquivo para o Dropbox
Este é um passo simples. Para carregar um ficheiro para o Dropbox, executaremos um procedimento armazenado “SP_UPLOADFILE” que chama as APIs necessárias no Dropbox para carregar um ficheiro. Para simplificar, vamos carregar um ficheiro de texto.
SP_UPLOADFILE:
EXEC SP_UPLOADFILE '@caminho', '@nome do ficheiro', '@contente';
O procedimento de armazenamento acima está esperando o conteúdo do arquivo em bytes.
Gostaria de carregar um ficheiro de texto chamado “primeiro.txt” para o diretório raiz do Dropbox. O conteúdo do ficheiro será “Hello World”; conforme combinado, precisamos converter essa mensagem “Hello World” em bytes através do seu próprio código ou de qualquer conversor online.
EXEC SP_UPLOADFILE '/', 'first.txt', ‘SGVsbG8gV29ybGQ=’;
Nota: Para obter mais informações sobre tabelas e procedimentos armazenados oferecidos pelo conector Dropbox, consulte o “Referência Dropbox Connector” documento.
A Figura 8 e a Figura 9 abaixo mostram a execução e a saída do procedimento armazenado acima.

Figura 8: Upload de um arquivo para o Dropbox

Figura 9: Arquivo carregado
3.3 Conexão de cópia e declarações
Agora sabemos que podemos descarregar anexos do Exchange e também sabemos que podemos carregar documentos para o Dropbox. Nós também testamos as nossas instruções SQL. O que precisamos fazer agora é copiar a string de conexão do Query Analyzer e nossas instruções testadas para nossa aplicação C#.
Para copiar a conexão do analisador de consultas, basta clicar com o botão direito do mouse na conexão, clicar em Editar e ir para a aba Avançado e copiar o texto de lá, como mostrado abaixo na Figura 10.
Figura 10: Cópia do fio de ligação do Query Analyzer

Aqui estão as minhas cordas de ligação para ambos os sistemas alvo.
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'
Agora estamos prontos para abrir o visual studio.net e começar a implementar a nossa solução de integração C#.
4. Solução Walkthrough
4.1 Criar uma Nova Aplicação C#
Basta criar uma aplicação de consola simples. A nossa solução não requer nenhuma referência externa nem a implementação de pacotes de terceiros. A solução baseia-se em ODBC; portanto, só precisamos de importar os namespaces necessários para a nossa classe.
usando System.Data; usando System.Data.Odbc;
4.2 Criar e Abrir uma ligação ao Exchange
1. Especifique a cadeia de ligação
string connectionString = "Driver={Media Gateway ODBC Driver};IMPL=CORBA;HOST='localhost';PORT='8087';ACC='ACC_EXCH365_CU7';UID='martin';PWD='1234'";
2. Crie e abra a conexão:
usando (OdbcConnection conexão = nova OdbcConnection(connectionString)) { conexão.Open(); ………………………… }
4.3 Download de anexos do Exchange
1. Descarregue os IDs dos e-mails Exchange com anexos para uma DataTable “messageIDs”. Vamos usar um DataAdapter “messagesAdapter” para conectar e descarregar os IDs.
usando (OdbcDataAdapter messagesAdapter = novo OdbcDataAdapter("SELECT ID FROM Message where HasAttachment = true;", conexão))
{
messagesAdapter.Fill(messageIDs);
}
2. Para cada ID de e-mail na tabela “messageIDs”, obteremos uma lista de anexos “apenas para informação” e guardá-los-emos noutra DataTable “documentsListTable”. Iremos utilizar outro DataAdapter “documentsListAdapter” para obter essa lista de anexos.
foreach (DataRow messageIDRow in messageIDs.Rows)
{
string sqlQueryString = string.Format("EXEC SP_SELECT_ATTACHMENTS '{0}';",
messageIDRow["ID"]);
usando (OdbcDataAdapter documentsListAdapter = novo OdbcDataAdapter
(sqlQueryString, conexão))
documentsListAdapter.Fill(documentsListTable);
}
3. Para cada anexo na “documentsListTable”, obteremos o endereço e o utilizaremos para obter o anexo real e, em seguida, adicionaremos esse anexo a uma terceira tabela “documentsTable”. Utilizaremos outro DataAdapter “documentsAdapter” para obter os anexos/documentos.
foreach (DataRow documentInfoRow in documentsListTable.Rows)
{
string sqlQueryString = string.Format("EXEC SP_SAVE_ATTACHMENT '{0}';",
documentInfoRow["Endereço"]);
usando (documentsAdapter = novo OdbcDataAdapter(sqlQueryString, conexão))
documentsAdapter.Fill(documentsTable);
}
4. Para cada anexo descarregado com sucesso da troca, exibir uma mensagem para o usuário usando o nome do arquivo anexo.
foreach (DataRow documentRow in documentsTable.Rows)
Console.WriteLine(string.Format("{0} baixado!",
documentRow["OutFileName"]));
4.4 Fechar a ligação ao Exchange
se (conexão.Estado == ConexãoState.Open)
conexão.Fechar();
4.5 Criar e abrir uma conexão com o Dropbox
1. Especifique a cadeia de ligação
string connectionString = "Driver={Media Gateway ODBC Driver};IMPL=CORBA;HOST='localhost';PORT='8087';ACC='ACC_DRBX_CBD';UID='martin';PWD='1234'";
2. Crie e abra a conexão:
usando (OdbcConnection conexão = nova OdbcConnection(connectionString)) { conexão.Open(); ………………………… }
4.6 Carregar os anexos na Dropbox
Para cada ficheiro anexo no “documentosTabela”, obteremos o nome do ficheiro “OutFileName” e o conteúdo do ficheiro “OutBuffer” e guarde o ficheiro na raiz da pasta Dropbox “/”.
Não precisamos de um novo DataAdapter, só precisamos de um OdbcCommand baseado em “SP_UPLOADFILE” discutido anteriormente, e precisamos adicionar os parâmetros necessários a ele, para que possamos passar os valores necessários para o procedimento armazenado.
foreach (DataRow documentRow in documentsTable.Rows)
{
usando (comando OdbcCommand = novo comando OdbcCommand("Exec SP_UploadFile ?, ?, ?",
ligação))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("@caminho", "/");
command.Parameters.AddWithValue("@filename", documentRow["OutFileName"]); comando.Parameters.AddWithValue("@filename", documentRow["OutFileName"]);
command.Parameters.AddWithValue("@content", documentRow["OutBuffer"]); command.Parameters.AddWithValue("@content", documentRow["OutBuffer"]);
fileUploadStatus = (comando.ExecuteNonQuery() > 0) ? "Uploaded!" :
"Not Uploaded!";
Console.WriteLine("{0} : {1}", documentRow["OutFileName"],
fileUploadStatus);
}
}
4.7 Fechar a ligação ao Dropbox
se (conexão.Estado == ConexãoState.Open)
conexão.Fechar();
5. Executando a solução

Figura 11: Executando a solução

Figura 12: Conteúdo do Dropbox após a execução da solução
6. Notas sobre a solução
Tentamos manter a lógica da aplicação o mais simples possível, porém a lógica poderia ser melhorada salvando anexos de cada e-mail de troca em uma pasta separada, onde o nome da pasta poderia ser uma parte do ID da mensagem ou qualquer outro identificador único.
Por simplicidade, ignoramos muitos padrões de codificação essenciais, incluindo mas não limitados a:
1. Ter cordas de conexão em um arquivo de configuração
2. Como hashing e encriptar senhas usando um código hash e um sal
3. Implementar padrões de design como o Princípio da Responsabilidade Única ou ainda melhor, Princípio da Inversão de Dependência
7. Código Fonte Completo
usando o Sistema;
usando o System.Data;
usando System.Data.Odbc;
namespace MySolution
{
Programa de Aulas
{
vazio estático Main(string[] args)
{
//necessária ligação
string connectionString = string.Empty;
string sqlQueryString = string.Vazio;
conexão OdbcConnection;
comando OdbcCommand;
DataTable documentsTable = new DataTable();
OdbcDataAdapter messagesAdapter, documentsListAdapter, documentsAdapter;
DataTable messageIDs = novo DataTable();
DataTable documentsListTable = novo DataTable();
//criar ligação ao Exchange
connectionString = "Driver={Media Gateway ODBC Driver};IMPL=CORBA;HOST='localhost';PORT='8087';ACC='ACC_EXCH365_CU7';UID='martin';PWD='1234'";
usando (conexão = nova OdbcConnection(connectionString))
{
//ligação aberta
connection.Open();
//load message ids para mensagens com anexos
usando (mensagensAdaptador = novo Adaptador OdbcDataAdapter("SELECT ID FROM Message where HasAttachment = true;", conexão))
{
//fill messageIDs tabela com mensagens
messagesAdapter.Fill(messageIDs);
}
// para cada mensagem usando o id de mensagem, obter lista de anexos
foreach (DataRow messageIDRow in messageIDs.Rows)
{
sqlQueryString = string.Format("EXEC SP_SELECT_ATTACHMENTS '{0}';", messageIDRow["ID"]);
usando (documentsListAdapter = novo OdbcDataAdapter(sqlQueryString, conexão))
documentsListAdapter.Fill(documentsListTable);
}
//agrupar cada anexo e guardá-lo em documentosTabela
foreach (DataRow documentInfoRow in documentsListTable.Rows)
{
sqlQueryString = string.Format("EXEC SP_SAVE_ATTACHMENT '{0}';", documentInfoRow["Endereço"]);
usando (documentsAdapter = new OdbcDataAdapter(sqlQueryString, conexão))
documentsAdapter.Fill(documentsTable);
}
// dar feedback ao usuário que esses arquivos foram baixados
foreach (DataRow documentRow in documentsTable.Rows)
Console.WriteLine(string.Format("{0} download!", documentRow["OutFileName"]));
//fechar ligação ao Exchange
se (conexão.Estado == ConexãoState.Open)
conexão.Fechar();
}
//criar ligação à DropBox
connectionString = "Driver={Media Gateway ODBC Driver};IMPL=CORBA;HOST='localhost';PORT='8087';ACC='ACC_DRBX_CBD';UID='martin';PWD='1234'";
usando (conexão = nova OdbcConnection(connectionString))
{
//ligação aberta
connection.Open();
//documentar o status de status de carregamento de documentos placeholder
string fileUploadStatus = string.Empty;
// para cada documento que temos em nossos documentosTabela
foreach (DataRow documentRow in documentsTable.Rows)
{
//chamada um procedimento armazenado para carregar o arquivo
usando (comando = novo OdbcCommand("Exec SP_UploadFile ?, ?, ?", conexão))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("@caminho", "/");
command.Parameters.AddWithValue("@filename", documentRow["OutFileName"]); comando.Parameters.AddWithValue("@filename", documentRow["OutFileName"]);
command.Parameters.AddWithValue("@content", documentRow["OutBuffer"]); command.Parameters.AddWithValue("@content", documentRow["OutBuffer"]);
//cheque o status e exibição na tela
fileUploadStatus = (command.ExecuteNonQuery() > 0) ? "Uploaded!" Uploaded: "Not Uploaded!";
Console.WriteLine("{0} : {1}", documentRow["OutFileName"], fileUploadStatus);
}
}
//fechar ligação ao Dropbox
se (conexão.Estado == ConexãoState.Open)
conexão.Fechar();
}
// dar feedback ao usuário
Console.WriteLine("tudo feito...");
Console.ReadKey();
}
}
}
