Testade i dagarna återigen på att programmera i C# mot EWS API och denna gången gick jag in för det mer än sist för något halvår sedan jag först stötte på det. Förvisso har jag successivt gått över mer och mer mot .NET istället för klassisk ASP vbscript men jag är långt ifrån någon hacker på det.
Varför inte välja VB.NET framför C#.NET känns kanske konstigt men med lite noggrannare studie av koden i sig så kändes VB.NET som klassisk ASP fast mycket mer tillkrånglat. C# blev liksom ”börja om från början” vilket då kändes som att man inte trodde sig känna till koden. Jag sneglade först på VB.NET och tyckte det verkade enklare men när jag insåg att liknande funktioner i klassisk ASP inte alls var samma i VB så kändes valet ändå som givet åt C# (CSharp som det uttalas.).
Varför i hela friden sitter du med det?
Det är som ett tidsfördriv skulle man kunna säga. Som ett pussel eller ett korsord. Du löser inte pusslet fören alla bitar är på exakt rätt plats. En punkt, ett komma på fel ställe i koden innebär att koden inte fungerar. Först när all logik är på plats så funkar det och man känner sig oerhört stolt över vad man precis skapat. Man har gjort något från scratch av inget och lyckats att skapa ett script, en webbsida eller en applikation. Som en tom tavelduk som i slutänden visar ett skevt Mona Lisa leende. Till vilken nytta kan man ju fråga sig… Nä ingen alls … Varför löser man korsord, målar tavlor, ritar, bygger fågelholkar eller vad nu din hobby må vara.
För att återgå till rubriken så testar jag alltså på att programmera mot Microsoft Exchange server 2010 och dess programmerings API och konstaterade snabbt hur enkelt det var.
Med ett fåtal rader i Visual Studio så BAAMMM connected, å sen så bara funkade allt. Kunde få programmeringsvägen läsa min inbox, ta mail från min inkorg och dunka in det i en SQL server databas tillsammans med att få alla bifogade filerna nersparkad till en mapp.
Ser du ingen nytta med detta eller inte förstår någonting så vill du förmodligen att jag snart skall komma in på ett annat ämne eller så känner du dig bara tvingad att läsa allt jag skriver. Vilket fall som så om du klickar här nedanför på läs mer så ger jag lite kod exempel på hur enkelt det kan se ut i C# EWS koden.
Glöm nu inte att ha EWS API installerat på din dator samt att lägga till referens till Microsoft.Exchange.WebServices.dll i VisualStudio.
[csharp]
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using Microsoft.Exchange.WebServices.Data;
using System.Net;
using System.Configuration;
using System.Data.SqlClient;
using System.IO;
namespace MailParser
{
class Program
{
static void Main(string[] args)
{
// Hämta inställningar från APP.CONFIG
// Jag har lagt mina settings i APP.CONFIG för att slippa omkompilera appen vid minsta förändring
// Exempelvis vid mailbox byte, byte av lösen m.m.
string strURI = MailParser.Properties.Settings.Default.URI;
string strUID = MailParser.Properties.Settings.Default.UID;
string strPWD = MailParser.Properties.Settings.Default.PWD;
string strDOM = MailParser.Properties.Settings.Default.DOM;
string strFILEPATH = MailParser.Properties.Settings.Default.FILEPATH;
string strCONNSTRING = MailParser.Properties.Settings.Default.CONNSTRING;
// Sätt upp en anslutning mot exchange servern
SqlConnection myConnection = new SqlConnection(strCONNSTRING);
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
service.Credentials = new NetworkCredential(strUID, strPWD, strDOM);
service.Url = new Uri(strURI);
// Identifiera vad vi skall leta efter
ItemView view = new ItemView(1);
view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Ascending);
view.PropertySet = new PropertySet(
BasePropertySet.IdOnly,
ItemSchema.Subject,
ItemSchema.DateTimeReceived,
ItemSchema.UniqueBody,
ItemSchema.Importance,
ItemSchema.Attachments);
// Leta upp inkorgen för den användare vi angett i app.config
FindItemsResults<Item> findResults = service.FindItems(
WellKnownFolderName.Inbox,
new ItemView(1));
// Ställ in hur vi vill att mailbodyn skall hämtas som, HTML eller plain text, i detta all plain text.
// och då endast body delen som är unikt för detta mail inte tidigare konversationer från att man har svarat på mailet el. dyl
Console.WriteLine("Antal mail i inkorgen: " + findResults.TotalCount.ToString());
var propertySet = new PropertySet(ItemSchema.UniqueBody);
propertySet.RequestedBodyType = BodyType.Text;
// För varje mail vi hittar gör detta.
foreach (Item item in findResults)
{
var email = EmailMessage.Bind(service, item.Id, propertySet);
EmailMessage message = EmailMessage.Bind(service, item.Id);
EmailMessage messageatt = EmailMessage.Bind(service, item.Id, new PropertySet(BasePropertySet.FirstClassProperties, EmailMessageSchema.Attachments));
Console.WriteLine("Mail from: " + message.From.Address);
string stremailUniqueBody = email.UniqueBody;
string strIDFOLDER;
// Öppna anslutning mot SQL server och börja peta in data i min databas.
myConnection.Open();
try
{
SqlCommand myCommand = myConnection.CreateCommand();
myCommand.CommandText = "INSERT INTO dbo.caseTB" +
"(customer, contact, tel, email, message, regdate, emailID)" +
"VALUES (@customer, @contact, @tel, @email, @message, @regdate, @emailID)";
myCommand.Parameters.Add("@customer", SqlDbType.VarChar, 50);
myCommand.Parameters.Add("@contact", SqlDbType.VarChar, 50);
myCommand.Parameters.Add("@tel", SqlDbType.VarChar, 50);
myCommand.Parameters.Add("@email", SqlDbType.VarChar, 50);
myCommand.Parameters.Add("@message", SqlDbType.Text);
myCommand.Parameters.Add("@regdate", SqlDbType.DateTime);
myCommand.Parameters.Add("@emailID", SqlDbType.VarChar, 255);
myCommand.Parameters["@customer"].Value = "MAIL-KUND";
myCommand.Parameters["@contact"].Value = "MAIL-KONTAKT";
myCommand.Parameters["@tel"].Value = "MAIL-TEL";
myCommand.Parameters["@email"].Value = message.From.Address;
myCommand.Parameters["@message"].Value = stremailUniqueBody;
myCommand.Parameters["@regdate"].Value = item.DateTimeReceived;
myCommand.Parameters["@emailID"].Value = item.Id.ToString();
myCommand.ExecuteNonQuery();
myCommand.Parameters.Clear();
myCommand.CommandText = "SELECT @@IDENTITY";
Console.WriteLine("Successfully added mail to db table");
// Få tillbaka id:t på den nyligen inmatade raden i sqlservern
// så att vi kan lagra de bifogade filerna i en mapp som motsvarar id:t på raden i sqlservern.
int insertID = Convert.ToInt32(myCommand.ExecuteScalar());
strIDFOLDER = insertID.ToString();
myCommand.Dispose();
myCommand = null;
}
catch (Exception ex)
{
// Skiter sig SQL insert så tala om vad som gått fel
throw new Exception(ex.ToString(), ex);
}
finally
{
myConnection.Close();
}
if (Directory.Exists(strFILEPATH + strIDFOLDER))
{
// ok, mappen finns redan
}
else
{
// Fil mappen som motsvarar id:t på jobbet finns inte, skapa innan vi skall lagra ner de bifogade filerna.
Directory.CreateDirectory(strFILEPATH + strIDFOLDER);
}
// Mailet vi har läst in, skriv den info till en textfil i vår filsökväg för just detta mail
using (System.IO.StreamWriter file = new System.IO.StreamWriter(@strFILEPATH + strIDFOLDER + "\\E-Mail-Message-" + item.Id + ".txt", true))
{
file.WriteLine(@"———————MAIL BEGIN———————–");
file.WriteLine(@"Meddelande ID: " + item.Id);
file.WriteLine(@"");
file.WriteLine(@item.DateTimeReceived);
file.WriteLine(@"Skickad med prio: " + item.Importance);
file.WriteLine(@"Från: " + message.Sender.Name + " <" + message.From.Address + ">");
file.WriteLine(@"Ämne: " + item.Subject);
file.WriteLine(@"");
file.WriteLine(@"——————-MESSAGE BEGIN———————-");
file.WriteLine(email.UniqueBody);
file.WriteLine(@"——————–MESSAGE END———————–");
file.WriteLine(@"");
file.WriteLine(@"Finns bifogade filer: ");
file.WriteLine(@item.HasAttachments);
file.WriteLine(@"");
// Om mailet har bifogade filer
if (messageatt.HasAttachments)
{
// För varje bifogad fil i mailet
foreach (FileAttachment fileAttachment in messageatt.Attachments)
{
// Spara ner filen till vår filsökväg men innan vi gör det så ta bort konstiga tecken i filnamnet.
// så som " ’ : och allt annat konstigt som inte tillåts i filnamn eller på webben
// Regex funktionen vi kallar på (RemoveInvalidFilenameCharacters) hittas längst ner i koden.
// När filen har fått ett nytt filnamn och är lagrad så skriv infon till vår textfil
fileAttachment.Load(strFILEPATH + strIDFOLDER + "\\" + RemoveInvalidFilenameCharacters(fileAttachment.Name));
file.WriteLine(RemoveInvalidFilenameCharacters(fileAttachment.Name));
}
}
file.WriteLine(@"———————MAIL END————————-");
file.WriteLine(@"");
file.WriteLine(@"");
file.WriteLine(@"——————————————————");
file.WriteLine(@" Mail parser v1.4 for Exchange2010 sp1 by Slint, Joko-Ono");
file.WriteLine(@"——————————————————");
}
// Nu har vi läst mailet och kan flytta det till borttaget.
// Istället för MoveToDeletedItems kan man skriva HardDelete vilket gör så att mailet raderas från boxen och finns inte mer.
email.Delete(DeleteMode.MoveToDeletedItems);
}
}
// Funktionen för att ta bort konstiga tecken i filnamn
public static string RemoveInvalidFilenameCharacters(string filename)
{
if (!string.IsNullOrEmpty(filename))
{
char[] invalidFilenameCharacters =
// Invalid for SharePoint… Nedanför visas massa konstiga tecken och det är bara att ta bort eller lägga till tecken som man vill hantera.
// som det är nu har jag valt att radera dessa tecken: \"#%&*/:<>?\\{|}~ åäöÅÄÖ¤´^§½`() och ersätta dem med inget.
// Så filnamnet Snökedjor "stora snökedjor" är bra att ha!.txt blir istället Snkedjorstorasnkedjorrbraattha!.txt
("\"#%&*/:<>?\\{|}~ åäöÅÄÖ¤´^§½`()".ToCharArray()).Union(
// File system…
System.IO.Path.GetInvalidPathChars()).Union(
System.IO.Path.GetInvalidFileNameChars()).Union(
// Environment variables
new char[] { System.IO.Path.PathSeparator }).ToArray();
foreach (char character in invalidFilenameCharacters)
{
// Ersätt ful tecknet med ett tomt tecken. string.Empty
filename = filename.Replace(
character.ToString(), string.Empty);
}
}
return filename;
}
}
}
[/csharp]
Lämna ett svar