问题
This code works on my local with Exchange hosted a VM, but not when trying to recieve mails from the clients Exchange server.
The point is to check a mailbox, extract details, start a workflow and attach email and any other attachments in the email, and move the email from the Inbox folder to my custom folder 'Saved'. This all works on my local machine.
These are the errors I get:
The request failed. The underlying connection was closed: An unexpected error occurred on a send.
Inner Exception: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
My code breaks at this point:
FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Inbox, view);
Please excuse any other shitty code, its not production ready and this is a shortened version I edited so items may be missing.
Here is the rest of the code. (I have a separate class that does the Authentication and holds all the credentials for mailboxes. I have listed that first)
private static bool RedirectionUrlValidationCallback(string redirectionUrl)
{
// The default for the validation callback is to reject the URL.
bool result = false;
Uri redirectionUri = new Uri(redirectionUrl);
// Validate the contents of the redirection URL. In this simple validation
// callback, the redirection URL is considered valid if it is using HTTPS
// to encrypt the authentication credentials.
if (redirectionUri.Scheme == "https")
{
result = true;
}
return result;
}
public static ExchangeService ConnectToService(IUserData userData)
{
return ConnectToService(userData,null);
}
public static ExchangeService ConnectToService(IUserData userData, ITraceListener listener)
{
ExchangeService service = new ExchangeService(userData.Version);
if (listener != null)
{
service.TraceListener = listener;
service.TraceFlags = TraceFlags.All;
service.TraceEnabled = true;
}
service.Credentials = new NetworkCredential(userData.EmailAddress, userData.Password);
if (userData.AutodiscoverUrl == null)
{
Uri myUri = new Uri("https://IPAddress/ews/exchange.asmx");
System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(myUri);
var test = webRequest.RequestUri;
webRequest.Proxy.IsBypassed(test);
webRequest.ClientCertificates.Clear();
webRequest.KeepAlive = false;
service.KeepAlive = false;
//NEW ****** ATTEMPTED FIXES
webRequest.Accept = "*/*";
service.AcceptGzipEncoding = true;
webRequest.ProtocolVersion = System.Net.HttpVersion.Version10;
var version = service.RequestedServerVersion;
userData.Version.Equals(ExchangeVersion.Exchange2013);
userData.AutodiscoverUrl = myUri;
service.Url = myUri;
}
else
{
service.Url = userData.AutodiscoverUrl;
}
return service;
}
public static ExchangeService ConnectToServiceWithImpersonation(
IUserData userData,
string impersonatedUserSMTPAddress)
{
return ConnectToServiceWithImpersonation(userData, impersonatedUserSMTPAddress, null);
}
public static ExchangeService ConnectToServiceWithImpersonation(
IUserData userData,
string impersonatedUserSMTPAddress,
ITraceListener listener)
{
ExchangeService service = new ExchangeService(userData.Version);
if (listener != null)
{
service.TraceListener = listener;
service.TraceFlags = TraceFlags.All;
service.TraceEnabled = true;
}
service.Credentials = new NetworkCredential(userData.EmailAddress, userData.Password);
ImpersonatedUserId impersonatedUserId =
new ImpersonatedUserId(ConnectingIdType.SmtpAddress, impersonatedUserSMTPAddress);
service.ImpersonatedUserId = impersonatedUserId;
if (userData.AutodiscoverUrl == null)
{
service.AutodiscoverUrl(userData.EmailAddress, RedirectionUrlValidationCallback);
userData.AutodiscoverUrl = service.Url;
}
else
{
service.Url = userData.AutodiscoverUrl;
}
return service;
}
THIS IS WHERE THE FUNCTIONALITY HAPPENS, AND CODE BREAKS @ FindItemsResults findResults = service.FindItems(WellKnownFolderName.Inbox, view);
static void RecieveMails(ExchangeService service)
{
string SitePath = @"C:\temp\";
int numOfFiles = 0;
int numOfAttachments = 0;
int fileCount = 0;
int filePosition = -1;
string pickupPath = Path.Combine(SitePath);
string uniqueRefNo;
Random memberNo = new Random();
string memberNumber = memberNo.Next().ToString();
ClientCredentials cc = new ClientCredentials();
var username = cc.UserName.ToString();
var service2 = new Microsoft.Exchange.WebServices.Data.ExchangeService();
var sVersion = service2.RequestedServerVersion;
var testVersion = service.RequestedServerVersion;
// Create a view with a page size of 10.
ItemView view = new ItemView(1);
// Indicate that the base property will be the item identifier
view.PropertySet = new PropertySet(BasePropertySet.FirstClassProperties);
view.PropertySet.Add(ItemSchema.IsAssociated);
// Set the traversal to associated. (Shallow is the default option; other options are Associated and SoftDeleted.)
view.Traversal = ItemTraversal.Associated;
//////Trust all certificates
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };
service.HttpHeaders.Values.DefaultIfEmpty("*/*");
service.HttpResponseHeaders.Add("Accept", "*/*");
service.KeepAlive = false;
service2.KeepAlive = false;
** /////** BREAKS HERE AT FindItems** /////**
FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Inbox, view);
findResults = service.FindItems(
WellKnownFolderName.Inbox,
new ItemView(1)); //# is the number of mails to fetch
foreach (Item item in findResults.Items)
{
//this needs to be here to recieve the message body
MessageBody messageBody = new Microsoft.Exchange.WebServices.Data.MessageBody();
List<Item> items = new List<Item>();
if (findResults.Items.Count > 0) // Prevent the exception
{
foreach (Item item2 in findResults)
{
items.Add(item2);
}
}
service.LoadPropertiesForItems(items, PropertySet.FirstClassProperties);
messageBody = item.Body.ToString().Replace("<html dir=", "").Replace("<head>", "").Replace("<meta http-equiv=", "").Replace("content=", "")
.Replace("<style type=", "").Replace("</style>", "").Replace("</head>", "").Replace("<body fpstyle=", "").Replace("ocsi=", "")
.Replace("<div style=", "").Replace("direction: ltr;font-family: Tahoma;color: #000000;font-size: 10pt;", "").Replace("</div>", "")
.Replace("<div>", "").Replace("</body>", "").Replace("</html>", "").Replace("<br>", "").Replace(">", "").Replace("\"Content-Type", "")
.Replace("\"text/html; charset=utf-8", "").Replace("\"0", "").Replace("\"", "").Replace("text/css", "")
.Replace("id=owaParaStyle", "").Replace("ltr", "").Replace("<meta name=GENERATOR MSHTML 9.00.8112.16470", "").Replace("<style P {", "")
.Replace("MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px", "").Replace("<p", "").Replace("</p>", "").Replace("</p", "").Replace(" ", "")
.Replace("<body fPStyle= ", "").Replace("%", "").Replace("<", "").Replace(">", "").Replace("}", "").Replace("\"","").Replace("body fPStyle=1","");//.Replace("\"1", "")
//messageBody = Regex.Replace(messageBody, @"(?:\r\n|\r(?!\n)|(?!<\r)\n){2,}", "");
string subject = item.Subject.ToString();
//Write results to Console
Console.WriteLine("==========================================================================");
Console.WriteLine("To: " + item.DisplayTo);
Console.WriteLine("Subject: " + subject);
Console.WriteLine("Message Body: " + messageBody);
Console.WriteLine();
Console.WriteLine("Date & Time Received: " + item.DateTimeReceived);
Console.WriteLine("HasAttachments: " + item.HasAttachments);
Console.WriteLine();
//saving email content to local drive
string fileDateTime = item.DateTimeReceived.ToString();
fileDateTime = fileDateTime.Replace("/", "-").Replace(":", "-");
string newFileName = "Email " + fileDateTime + " - " + "E_Subject- " + item.Subject.Replace(":", "").Replace("*", "").Replace(".", "").Replace(",", "")
.Replace(";", "").Replace("?", "").Replace("<p", "").Replace("</p>", "").Replace("</p", "")
.Replace("<meta name=GENERATOR MSHTML 9.00.8112.16470", "").Replace("<style P {", "").Replace("MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px", "")
.Replace("}", "").Replace("/", "").Replace("&", "").Replace("#", "").Replace("@", "").Replace("!", "")
.Replace("%", "").Replace("<", "").Replace(">", "").Replace(" ", "").Replace("<body fPStyle= ", "");
string mydocpath = SitePath + newFileName + ".txt";
string From = ((Microsoft.Exchange.WebServices.Data.EmailAddress)item[EmailMessageSchema.From]).Address;
string WFType = subject;
string DocumentType = "From Email";
int WFTypeID = PPS.SM.Services.WorkflowDataService.GetWFTypeID(WFType);
StringBuilder sb = new StringBuilder();
//Text file content
sb.AppendLine("Sent From: " + From);
sb.AppendLine("Sent To: " + item.DisplayTo);
sb.AppendLine("Email Subject: " + subject);
sb.AppendLine("Date and time received: " + item.DateTimeReceived.ToString());
sb.AppendLine("CC: " + item.DisplayCc);
sb.AppendLine("Number of Attachments: " + item.Attachments.Count.ToString());
sb.AppendLine();
sb.AppendLine("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
sb.AppendLine();
sb.Append("Email message body: " + messageBody);
sb.AppendLine();
using (StreamWriter outfile = new StreamWriter(mydocpath, true))
{
outfile.WriteLine(sb.ToString());
}
//Save attachments to local drive
int attCount = item.Attachments.Count();
foreach (Attachment attachment in item.Attachments)
{
if (attachment is FileAttachment)
{
FileAttachment fileAttachment = attachment as FileAttachment;
fileAttachment.Load();
Console.WriteLine("Attachment name: " + fileAttachment.Name);
string attname = newFileName.Replace("Email ", "");
//File location
fileAttachment.Load(SitePath + "Attachment " + attname + " -Att_Fname- " + fileAttachment.Name); // Stream attachment contents into a file.
}
else// Attachment is an item attachment.
{
// Load attachment into memory and write out the subject.
ItemAttachment itemAttachment = attachment as ItemAttachment;
itemAttachment.Load();
string attname = newFileName.Replace("Email ", "");
Console.WriteLine("Attachment " + attname + itemAttachment.Name);
}
}
PPS.SM.IAASMAgent.SMAgent client = new PPS.SM.IAASMAgent.SMAgent();
var result = client.CreateWorkflow(WFTypeID, "iaasystem", "$1Elvis", "iquitowitz", "", "", "EmailService", "FromEmail", "", "", "", "", memberNumber, "South Africa", "FGV256", "", "", "", "", "", "", 0, "", "", "", false, false, "", "", "", 0, "", false, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", decimal.Parse("0"), false, false, true).ToString();
Console.WriteLine(result);
string WFnum = result.Substring(result.IndexOf('>', result.LastIndexOf("<Workflownumber>")) + 1);
WFnum = WFnum.Split('<')[0];
int WFnumber = int.Parse(WFnum.ToString());
string IDNumber = result.Substring(result.IndexOf('>', result.LastIndexOf("<IDNumber>")) + 1);
IDNumber = IDNumber.Split('<')[0];
foreach (string file in Directory.GetFiles(pickupPath, "*"))
{
bool contains = false;
if (contains = Regex.Match(file.ToString(), item.DateTimeReceived.ToString().Replace("/", "-").Replace(":", "-"), RegexOptions.IgnoreCase).Success)
{
fileCount++;
}
}
var WFattachment = new string[fileCount];
ConfigurationManager.RefreshSection("applicationSettings");
string sp = ConfigurationManager.AppSettings["UploadToSharePoint"];
string dc = ConfigurationManager.AppSettings["UploadToDocumentum"];
Console.WriteLine(ConfigurationManager.AppSettings["UploadToSharePoint"]);
Console.WriteLine(ConfigurationManager.AppSettings["UploadToDocumentum"]);
AgentServiceClient asc = new AgentServiceClient();
//Upload to Sharepoint
if (sp == "True")
{
PPS.SM.DocumentumAgentService.AgentServiceClient client2 = new PPS.SM.DocumentumAgentService.AgentServiceClient();
if (Directory.Exists(pickupPath))
{
foreach (string file in Directory.GetFiles(pickupPath, "*"))
{
bool contains = false;
if (contains = Regex.Match(file.ToString(), item.DateTimeReceived.ToString().Replace("/", "-").Replace(":", "-"), RegexOptions.IgnoreCase).Success)
{
filePosition++;
Console.WriteLine("Regex match: " + contains.ToString());
numOfFiles++;
if ((contains = Regex.Match(file.ToString(), "Email", RegexOptions.IgnoreCase).Success) && (contains != Regex.Match(file.ToString(), "Attachment", RegexOptions.IgnoreCase).Success))//this file is an email
{
WFattachment[filePosition] = file.ToString();
byte[] bytesfile = System.IO.File.ReadAllBytes(file.ToString());
uniqueRefNo = PPS.SM.Services.WorkflowDataService.GenerateDocRefNo();
string documentGroup = client2.GetDocumentGroup(DocumentType);
var createdDate = DateTime.Now.Date;
var contentType = new FileInfo(file).Extension;
client2.UploadFile("iquitowitz", WFnumber, bytesfile, file.ToString(), "South Africa", "FromEmail", memberNumber, "Test", WFType, documentGroup, "EmailService", IDNumber, "1900-01-01 00:00:00.000", 3, uniqueRefNo, "Sharepoint", int.Parse(memberNumber), "",contentType, createdDate);
//assoiciate as document to workflow
if (dc == "False")
{
File.Delete(file);
}
//}
}
else //this file is an attachment
{
//add file to WF
Console.WriteLine("Attachment file found on local drive @ " + file.ToString());
Console.WriteLine("\n");
numOfAttachments++;
WFattachment[filePosition] = file.ToString();
byte[] bytesfile = System.IO.File.ReadAllBytes(file.ToString());
uniqueRefNo = PPS.SM.Services.WorkflowDataService.GenerateDocRefNo();
string documentGroup = client2.GetDocumentGroup(DocumentType);
var createdDate = DateTime.Now.Date;
var contentType = new FileInfo(file).Extension;
client2.UploadFile("ServiceManager", WFnumber, bytesfile, file.ToString(), "South Africa", "FromEmail", memberNumber, "Test", WFType, documentGroup, "EmailService", IDNumber, "1979-06-19 00:00:00.000", 3, uniqueRefNo, "Sharepoint", int.Parse(memberNumber), "", contentType, createdDate);
if (dc == "False")
{
File.Delete(file);
}
}
}
}
}
}
filePosition = -1;
//Upload to Documentum
if (dc == "True")
{
if (Directory.Exists(pickupPath))
{
foreach (string file in Directory.GetFiles(pickupPath, "*"))
{
bool contains = false;
if (contains = Regex.Match(file.ToString(), item.DateTimeReceived.ToString().Replace("/", "-").Replace(":", "-"), RegexOptions.IgnoreCase).Success)
{
filePosition++;
Console.WriteLine("Regex match: " + contains.ToString());
numOfFiles++;
if ((contains = Regex.Match(file.ToString(), "Email", RegexOptions.IgnoreCase).Success) && (contains != Regex.Match(file.ToString(), "Attachment", RegexOptions.IgnoreCase).Success)) //this file is an email
{
Console.WriteLine("\n");
WFattachment[filePosition] = file.ToString();
byte[] bytesfile = System.IO.File.ReadAllBytes(file.ToString());
var docresult = asc.UploadDocument("iquitowitz", "p", WFnumber, bytesfile, file.ToString().Replace(SitePath, ""), "South Africa", "FromEmail", memberNumber, "", WFType, "", IDNumber, "", 3);
Console.WriteLine(docresult);
//if success
File.Delete(file);
//}
}
else if (contains = Regex.Match(file.ToString(), "Attachment", RegexOptions.IgnoreCase).Success) //this file is an attachment
{
//add file to WF
Console.WriteLine("Attachment file found on local drive @ " + file.ToString());
Console.WriteLine("\n");
//numOfAttachments++;
WFattachment[filePosition] = file.ToString();
byte[] bytesfile = System.IO.File.ReadAllBytes(file.ToString());
var docresult = asc.UploadDocument("ServiceManager", "p", WFnumber, bytesfile, file.ToString().Replace(SitePath, ""), "South Africa", "FromEmail", memberNumber, "", WFType, "", IDNumber, "", 3);
Console.WriteLine(docresult);
//if success
File.Delete(file);
}
}
}
}
}
Console.WriteLine("Number of attachment files found on local drive: " + numOfAttachments.ToString());
if (fileCount != 0)
for (int i = 0; i < fileCount; )
{
Console.WriteLine("Attachment Location: " + WFattachment[i]);
i++;
if (i != fileCount)
{
Console.WriteLine("");
}
}
//if (WorkflowWasCreated) then move email to saved folder
//here I move the mail to my custom folder "Saved"
Folder rootfolder = Folder.Bind(service, WellKnownFolderName.MsgFolderRoot);
rootfolder.Load();
foreach (Folder folder in rootfolder.FindFolders(new FolderView(100)))
{
// This IF limits what folder the program will seek
if (folder.DisplayName == "Saved")
{
var fid = folder.Id;
//Console.WriteLine(fid);
item.Load();
//item.Subject = (fileDateTime) +" - " + subject.ToString();
item.Update(ConflictResolutionMode.AlwaysOverwrite);
item.Move(fid);
Console.WriteLine("\n");
Console.WriteLine("Email moved from Inbox to: '" + folder.DisplayName + "' folder as '" + item.Subject + "'");
}
}
}
}
回答1:
I found the issue, which was a mission as I had to get extra information from a Server Engineer at the client. After trying a bunch os scenarios we found the issue. The problem was here:
Uri myUri = new Uri("https://IPAddress/ews/exchange.asmx");
where I was using the Exchange servers's IP address. Instead I have to go via webmail and the company domian
Uri myUri = new Uri("https://webmail.CompanyDomain.com/ews/exchange.asmx");
and then this service worked. Hope this can help anyone who comes along an issue like this.
来源:https://stackoverflow.com/questions/17236956/retrieving-mails-from-a-remote-exchange-server-some-sort-of-security-issue