--
Peter
Thank You
Post by Lee Derbyshire [MVP]Post by Peter--
Peter
Thank You
Post by Lee Derbyshire [MVP]Post by Peter--
Peter
Thank You
Post by Lee Derbyshire [MVP]Post by Peter(Exchange 2003)
I am trying to retrieve an attachment from an email using C# with the
following code, the messages which are sent internally of the domain work
just fine, but the messages sent from outside the domain get 404
error
when
trying to retrieve the attachment.
What am I doing wrong?
Here's the code.
//
// here's the value of the attachmentFile
//
//
http://ex/exchange/ediadmin/Inbox/7153458667.xls.EML/7153458667.xls
//
System.Net.WebClient wcClient = new System.Net.WebClient();
wcClient.Credentials = new
System.Net.NetworkCredential(user,password,
domain);
wcClient.DownloadFile(attachmentFile, attachmentName); // <-- This is
where the error occurs
Can you find the 404 entry in the IIS log file?
Lee.
--
______________________________________
Outlook Web Access For PDA , OWA For WAP
www.leederbyshire.com
lee a.t leederbyshire d.o.t c.o.m
______________________________________
Yes I can, here's the entry
2009-06-02 13:19:07 W3SVC100 10.100.0.180 GET
/exchange/ediadmin/Inbox/777720602.xls.EML/777720602.xls - 80
VANHOOF\Services 10.100.0.177 - 404 0 0
2009-06-02 13:19:07 W3SVC100 10.100.0.180 GET
/exchange/ediadmin/Inbox/777720602.xls.EML/777720602.xls - 80 - 10.100.0.177
- 401 2 2148074254
and here's the same email after it was forwarded
2009-06-02 13:26:08 W3SVC100 10.100.0.180 GET
/exchange/ediadmin/Inbox/FW:+777720602.xls.EML/777720602.xls - 80
VANHOOF\Services 10.100.0.177 - 200 0 0
2009-06-02 13:26:08 W3SVC100 10.100.0.180 GET
/exchange/ediadmin/Inbox/FW:+777720602.xls.EML/777720602.xls - 80 -
10.100.0.177 - 401 2 2148074254
Are you sure you have the correct URL? I assume you're getting it with
X-MS-ENUMATTS? What does the X-MS-ENUMATTS response look like?
2009-06-02 13:19:07 W3SVC100 10.100.0.180 X-MS-ENUMATTS
/exchange/ediadmin/Inbox/777720602.xls.EML - 443 - 10.100.0.177 - 401 2
2148074254
2009-06-02 13:19:07 W3SVC100 10.100.0.180 X-MS-ENUMATTS
/exchange/ediadmin/Inbox/777720602.xls.EML - 443 - 10.100.0.177 - 401 1 0
2009-06-02 13:19:07 W3SVC100 10.100.0.180 X-MS-ENUMATTS
/exchange/ediadmin/Inbox/777720602.xls.EML - 443 VANHOOF\services
10.100.0.177 - 207 0 0
2009-06-02 13:26:08 W3SVC100 10.100.0.180 X-MS-ENUMATTS
/exchange/ediadmin/Inbox/FW:+777720602.xls.EML - 443 - 10.100.0.177 - 401 2
2148074254
2009-06-02 13:26:08 W3SVC100 10.100.0.180 X-MS-ENUMATTS
/exchange/ediadmin/Inbox/FW:+777720602.xls.EML - 443 - 10.100.0.177 - 401 1 0
2009-06-02 13:26:08 W3SVC100 10.100.0.180 X-MS-ENUMATTS
/exchange/ediadmin/Inbox/FW:+777720602.xls.EML - 443 VANHOOF\services
10.100.0.177 - 207 0 0
I was wondering what the actual text returned by the server in response to
the enumatts request was. I am just trying to find out if the URL is
actually what you think it is. They aren't always so predictable -
sometimes they get turned into something that looks like a long GUID. Can
you open the attachment in OWA? What is recorded in the log file when you
do that?
Here's a fix provided by Microsoft Tech Support:
public static List<Attachment> GetAttachments(string email)
{
// Variables.
System.Net.HttpWebRequest Request;
System.Net.WebResponse Response;
System.Net.CredentialCache MyCredentialCache;
string strMessageURI = email;
string user = AppSettings.MailBoxUserID;
string password = AppSettings.MailBoxUserPassword;
string domain = AppSettings.MailBoxDomain;
string path =
Utility.FixPath.FixPathSeparator(AppSettings.WorkPath);
System.IO.Stream ResponseStream = null;
System.Xml.XmlDocument ResponseXmlDoc = null;
System.Xml.XmlNode root = null;
System.Xml.XmlNamespaceManager nsmgr = null;
System.Xml.XmlNodeList PropstatNodes = null;
System.Xml.XmlNodeList HrefNodes = null;
System.Xml.XmlNode StatusNode = null;
System.Xml.XmlNode PropNode = null;
List<Attachment> attachments = new List<Attachment>();
try
{
// Create a new CredentialCache object and fill it with the
network
// credentials required to access the server.
MyCredentialCache = new System.Net.CredentialCache();
MyCredentialCache.Add(new System.Uri(strMessageURI), "NTLM",
new System.Net.NetworkCredential(user, password, domain)
);
// Create the HttpWebRequest object.
Request =
(System.Net.HttpWebRequest)HttpWebRequest.Create(strMessageURI);
// Add the network credentials to the request.
Request.Credentials = MyCredentialCache;
// Specify the method.
Request.Method = "X-MS-ENUMATTS";
// Send the X-MS-ENUMATTS method request and get the
// response from the server.
if (Request != null)
{
Response = (HttpWebResponse)Request.GetResponse();
// Get the XML response stream.
ResponseStream = Response.GetResponseStream();
// Create the XmlDocument object from the XML response
stream.
ResponseXmlDoc = new System.Xml.XmlDocument();
// Load the XML response stream.
ResponseXmlDoc.Load(ResponseStream);
// Get the root node.
root = ResponseXmlDoc.DocumentElement;
// Create a new XmlNamespaceManager.
nsmgr = new
System.Xml.XmlNamespaceManager(ResponseXmlDoc.NameTable);
// Add the DAV: namespace, which is typically assigned
the a: prefix
// in the XML response body. The namespaceses and their
associated
// prefixes are listed in the attributes of the
DAV:multistatus node
// of the XML response.
nsmgr.AddNamespace("a", "DAV:");
// Add the http://schemas.microsoft.com/mapi/proptag/
namespace, which
// is typically assigned the d: prefix in the XML
response body.
nsmgr.AddNamespace("d",
"http://schemas.microsoft.com/mapi/proptag/");
// Use an XPath query to build a list of the
DAV:propstat XML nodes,
// corresponding to the returned status and properties of
// the file attachment(s).
PropstatNodes = root.SelectNodes("//a:propstat", nsmgr);
// Use an XPath query to build a list of the DAV:href
nodes,
// corresponding to the URIs of the attachement(s) on
the message.
// For each DAV:href node in the XML response, there is an
// associated DAV:propstat node.
HrefNodes = root.SelectNodes("//a:href", nsmgr);
// Attachments found?
if (HrefNodes.Count > 0)
{
// Display the number of attachments on the message.
// Console.WriteLine(HrefNodes.Count + "
attachments found...");
// Iterate through the attachment properties.
for (int i = 0; i < HrefNodes.Count; i++)
{
// Use an XPath query to get the DAV:status node
from the DAV:propstat node.
StatusNode =
PropstatNodes[i].SelectSingleNode("a:status", nsmgr);
// Check the status of the attachment properties.
if (StatusNode.InnerText != "HTTP/1.1 200 OK")
{
// Console.WriteLine("Attachment: "
+ HrefNodes[i].InnerText);
// Console.WriteLine("Status: " +
StatusNode.InnerText);
// Console.WriteLine("");
}
else
{
// Console.WriteLine("Attachment: " +
HrefNodes[i].InnerText);
// Console.WriteLine("Status: " +
StatusNode.InnerText);
// Get the CdoPR_ATTACH_FILENAME_W MAPI
property tag,
// corresponding to the attachment file
name. The
//
http://schemas.microsoft.com/mapi/proptag/ namespace is typically
// assigned the d: prefix in the XML
response body.
// PropNode =
PropstatNodes[i].SelectSingleNode("a:prop/d:x3704001f", nsmgr);
// Console.WriteLine("Attachment name: " +
PropNode.InnerText);
// Get the CdoPR_ATTACH_EXTENSION_W MAPI
property tag,
// corresponding to the attachment file
extension.
PropNode =
PropstatNodes[i].SelectSingleNode("a:prop/d:x3703001f", nsmgr);
if(PropNode == null)
PropNode =
PropstatNodes[i].SelectSingleNode("a:prop/d:x3704001f", nsmgr);
if (PropNode != null &&
PropNode.InnerText.ToLower().IndexOf(".xls") > -1)
{
try
{
//HrefNodes[i].InnerText,
PropNode.InnerText
DownloadAttachment(HrefNodes[i].InnerText, path + PropNode.InnerText, user,
password, domain);
attachments.Add(new
Attachment(HrefNodes[i].InnerText, PropNode.InnerText));
}
catch (Exception aex)
{
Error_Logger.ErrorLogger.LogErrorToFile(aex.ToString());
attachments.Add(new
Attachment(email, email));
}
}
//Console.WriteLine("File extension: " +
PropNode.InnerText);
// Get the CdoPR_ATTACH_SIZE MAPI property
tag,
// corresponding to the attachment file size.
//PropNode =
PropstatNodes[i].SelectSingleNode("a:prop/d:x0e200003", nsmgr);
//Console.WriteLine("Attachment size: " +
PropNode.InnerText);
Console.WriteLine("");
}
}
}
else
{
//Console.WriteLine("No attachments found.");
}
// Clean up.
ResponseStream.Close();
Response.Close();
}
}
catch (Exception ex)
{
// Catch any exceptions. Any error codes from the
X-MS-ENUMATTS
// method request on the server will be caught here, also.
Console.WriteLine(ex.Message);
}
return attachments;
}
private static void DownloadAttachment(String emlURL, String
fileName, String user, String password, String domain)
{
System.Uri strURL = new System.Uri(emlURL);
// Create our request object
HttpWebRequest WebReq;
WebReq = (HttpWebRequest)WebRequest.Create(emlURL);
// Set the credentials. If user is blank then Windows Auth will
be used
if (user.Length != 0)
{
// Use Basic Authentication
NetworkCredential myCred = new NetworkCredential(user,
password, domain);
CredentialCache myCredentialCache = new CredentialCache();
myCredentialCache.Add(new System.Uri(emlURL), "NTLM", myCred);
WebReq.Credentials = myCredentialCache;
}
else
{
// Use Windows Authentication
WebReq.Credentials = CredentialCache.DefaultCredentials;
}
//Add the headers
WebReq.Headers.Add("Translate", "f");
WebReq.KeepAlive = true;
WebReq.AllowAutoRedirect = false;
WebReq.Method = "GET";
// Get the response for our request
HttpWebResponse WebResp = (HttpWebResponse)WebReq.GetResponse();
switch (WebResp.ContentType)
{
case "message/rfc822":
case "application/vnd.ms-excel":
case "application/octet-stream":
case "application/pdf":
case "application/msword":
Stream tmpStream = WebResp.GetResponseStream();
FileStream file = new FileStream(fileName,
System.IO.FileMode.Create);
byte[] buffer = new byte[4096];
int length;
length = tmpStream.Read(buffer, 0, 4096);
while (length > 0)
{
file.Write(buffer, 0, length);
length = tmpStream.Read(buffer, 0, 4096);
}
file.Close();
tmpStream.Close();
break;
case "text/plain":
case "text/xml":
StreamReader tmpStreamRead = new
StreamReader(WebResp.GetResponseStream());
string StrResponseData = tmpStreamRead.ReadToEnd();
tmpStreamRead.Close();
StreamWriter filetxt = new StreamWriter(fileName);
filetxt.Write(StrResponseData);
filetxt.Close();
break;
}
WebResp.Close();
}