|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Using Webdav for attachments in 2007Hi All,
I have a program that has been working on Exchange server 2003 for a few months now and the company upgraded to 2007. We made adjustments to the folder paths for the location of the OWA Authentication dll, and enabled FBA on the new server. With those changed in place should the same WebDav code work for 2007 or is WebDav just out of the question? I'm also looking at re-coding it to use Web Services but that'll be another story. TIA, Mike P.S. Thanks Glen for the helping with getting the attachments from the 'discussion' type. It did solve the problem and I marked it.
Show quote
Hide quote
"MVBaker" <MVBaker@newsgroup.nospam> wrote in message Yes, it will work the same. You changed the path for the auth dll, but note news:D0C47A46-6F8C-497E-A646-AC918287F745@microsoft.com... > Hi All, > I have a program that has been working on Exchange server 2003 for a few > months now and the company upgraded to 2007. We made adjustments to the > folder paths for the location of the OWA Authentication dll, and enabled > FBA > on the new server. With those changed in place should the same WebDav code > work for 2007 or is WebDav just out of the question? > I'm also looking at re-coding it to use Web Services but that'll be > another > story. > > TIA, > Mike > P.S. Thanks Glen for the helping with getting the attachments from the > 'discussion' type. It did solve the problem and I marked it. that the WebDAV (or plain GET, for attachment bodies) requests still go to /Exchange/ . Lee. -- _______________________________________ Outlook Web Access for PDA, OWA For WAP: www.leederbyshire.com ________________________________________
Show quote
Hide quote
"Lee Derbyshire [MVP]" wrote: Thanks for the info Lee. I've made it work from a test web page but it's > "MVBaker" <MVBaker@newsgroup.nospam> wrote in message > news:D0C47A46-6F8C-497E-A646-AC918287F745@microsoft.com... > > Hi All, > > I have a program that has been working on Exchange server 2003 for a few > > months now and the company upgraded to 2007. We made adjustments to the > > folder paths for the location of the OWA Authentication dll, and enabled > > FBA > > on the new server. With those changed in place should the same WebDav code > > work for 2007 or is WebDav just out of the question? > > I'm also looking at re-coding it to use Web Services but that'll be > > another > > story. > > > > TIA, > > Mike > > P.S. Thanks Glen for the helping with getting the attachments from the > > 'discussion' type. It did solve the problem and I marked it. > > Yes, it will work the same. You changed the path for the auth dll, but note > that the WebDAV (or plain GET, for attachment bodies) requests still go to > /Exchange/ . > > Lee. > reporting a (401) unauthorized when it runs in the production machine. What I have is a Windows Service app that reads a list of files from a db. The service looks for the files as attachments to incomming emails. But I can't get past the line that gets the WebResponse in the authentication function (which I've included below) Should this same authentication method work from a VB.NET exe app running as a service or is there something else I need to add? Thanks for the help. Mike mstrProtocol = "https://" strServerName is passed in and I've checked that it's correct I've also checked the user name and password by logging into OWA interactively. AuthenticateSecureOWA function ' Construct our destination URI. uriAuth = New System.Uri(mstrProtocol + strServerName + "/owa/auth/owaauth.dll") CookieJar = New CookieContainer ' Create our request object for the constructed URI. reqAuthRequest = CType(WebRequest.Create(uriAuth), HttpWebRequest) reqAuthRequest.CookieContainer = CookieJar ' Create our post data string that is required by OWA (owaauth.dll). Dim strPostFields As String = "destination=https%3A%2F%2F" & strServerName & "%2Fexchange%2F" & strUserName & "%2F&username=" & strDomain & "%5C" & strUserName & "&password=" & strPassword & "&SubmitCreds=LogOn&forcedownlevel=0&trusted=0" reqAuthRequest.KeepAlive = True reqAuthRequest.Expect = "" reqAuthRequest.Accept = "*/*" reqAuthRequest.AllowAutoRedirect = False reqAuthRequest.Method = "POST" ' Store the post data into a byte array. Dim bytPostData() As Byte = System.Text.Encoding.ASCII.GetBytes(strPostFields) ' Set the content length. reqAuthRequest.ContentLength = bytPostData.Length Dim tmpStream As Stream ' Create a request stream. Write the post data to the stream. tmpStream = reqAuthRequest.GetRequestStream() tmpStream.Write(bytPostData, 0, bytPostData.Length) tmpStream.Close() >>> this is the area that fails (401) unathorized is written to my log by the exception catch. ' Get the response from the request.Dim respAuthResp As HttpWebResponse = reqAuthRequest.GetResponse() ' Create a stream to capture the response data Dim tmpStreamRead As New StreamReader(respAuthResp.GetResponseStream()) ' Write returned data to a string. Dim strResponseData As String = tmpStreamRead.ReadToEnd() tmpStreamRead.Close() ' Close the response object. respAuthResp.Close() ' Get our returned cookie set, store it for use elsewhere mcookies = respAuthResp.Cookies
Show quote
Hide quote
"MVBaker" <MVBaker@newsgroup.nospam> wrote in message It's possible that the owaauth.dll is not available to anonymous users news:5FB6C0D6-A311-479F-8017-5977034226A7@microsoft.com... > > > "Lee Derbyshire [MVP]" wrote: > >> "MVBaker" <MVBaker@newsgroup.nospam> wrote in message >> news:D0C47A46-6F8C-497E-A646-AC918287F745@microsoft.com... >> > Hi All, >> > I have a program that has been working on Exchange server 2003 for a >> > few >> > months now and the company upgraded to 2007. We made adjustments to the >> > folder paths for the location of the OWA Authentication dll, and >> > enabled >> > FBA >> > on the new server. With those changed in place should the same WebDav >> > code >> > work for 2007 or is WebDav just out of the question? >> > I'm also looking at re-coding it to use Web Services but that'll be >> > another >> > story. >> > >> > TIA, >> > Mike >> > P.S. Thanks Glen for the helping with getting the attachments from the >> > 'discussion' type. It did solve the problem and I marked it. >> >> Yes, it will work the same. You changed the path for the auth dll, but >> note >> that the WebDAV (or plain GET, for attachment bodies) requests still go >> to >> /Exchange/ . >> >> Lee. >> > > Thanks for the info Lee. I've made it work from a test web page but it's > reporting a (401) unauthorized when it runs in the production machine. > What I > have is a Windows Service app that reads a list of files from a db. The > service looks for the files as attachments to incomming emails. But I > can't > get past the line that gets the WebResponse in the authentication function > (which I've included below) > Should this same authentication method work from a VB.NET exe app running > as > a service or is there something else I need to add? > > Thanks for the help. > Mike > > mstrProtocol = "https://" > strServerName is passed in and I've checked that it's correct > I've also checked the user name and password by logging into OWA > interactively. > > AuthenticateSecureOWA function > ' Construct our destination URI. > uriAuth = New System.Uri(mstrProtocol + strServerName + > "/owa/auth/owaauth.dll") > > CookieJar = New CookieContainer > ' Create our request object for the constructed URI. > reqAuthRequest = CType(WebRequest.Create(uriAuth), > HttpWebRequest) > reqAuthRequest.CookieContainer = CookieJar > ' Create our post data string that is required by OWA > (owaauth.dll). > Dim strPostFields As String = "destination=https%3A%2F%2F" & > strServerName & "%2Fexchange%2F" & strUserName & "%2F&username=" & > strDomain > & "%5C" & strUserName & "&password=" & strPassword & > "&SubmitCreds=LogOn&forcedownlevel=0&trusted=0" > reqAuthRequest.KeepAlive = True > reqAuthRequest.Expect = "" > reqAuthRequest.Accept = "*/*" > reqAuthRequest.AllowAutoRedirect = False > reqAuthRequest.Method = "POST" > ' Store the post data into a byte array. > Dim bytPostData() As Byte = > System.Text.Encoding.ASCII.GetBytes(strPostFields) > ' Set the content length. > reqAuthRequest.ContentLength = bytPostData.Length > Dim tmpStream As Stream > ' Create a request stream. Write the post data to the stream. > tmpStream = reqAuthRequest.GetRequestStream() > tmpStream.Write(bytPostData, 0, bytPostData.Length) > tmpStream.Close() >>>> this is the area that fails (401) unathorized is written to my log by >>>> the exception catch. > ' Get the response from the request. > Dim respAuthResp As HttpWebResponse = > reqAuthRequest.GetResponse() > ' Create a stream to capture the response data > Dim tmpStreamRead As New > StreamReader(respAuthResp.GetResponseStream()) > ' Write returned data to a string. > Dim strResponseData As String = tmpStreamRead.ReadToEnd() > tmpStreamRead.Close() > ' Close the response object. > respAuthResp.Close() > ' Get our returned cookie set, store it for use elsewhere > mcookies = respAuthResp.Cookies > (which it needs to be, since you haven't logged in yet). Check the IIS permissions, and the NTFS permissions in Explorer. The IIS log will show which resource is causing the problem, and may give a more specific error code. [SNIP]
> I asked IT support and they said that NTFS permissions are Read & Execute > It's possible that the owaauth.dll is not available to anonymous users > (which it needs to be, since you haven't logged in yet). Check the IIS > permissions, and the NTFS permissions in Explorer. The IIS log will show > which resource is causing the problem, and may give a more specific error > code. > > > and IIS permissions on the folder and the file are set correctly. Would it help to post more of the code from my app? Is there something in particular we can try to verify that things on the server are correct? Thanks again, Mike
Show quote
Hide quote
"MVBaker" <MVBaker@newsgroup.nospam> wrote in message It would be more help at the moment to post the iis log file entries, if you news:9225C3F4-99C5-4DD2-A6DA-7F14B5F42189@microsoft.com... > [SNIP] > >> >> It's possible that the owaauth.dll is not available to anonymous users >> (which it needs to be, since you haven't logged in yet). Check the IIS >> permissions, and the NTFS permissions in Explorer. The IIS log will show >> which resource is causing the problem, and may give a more specific error >> code. >> >> >> > > I asked IT support and they said that NTFS permissions are Read & Execute > and IIS permissions on the folder and the file are set correctly. Would it > help to post more of the code from my app? Is there something in > particular > we can try to verify that things on the server are correct? > > Thanks again, > Mike can get them?
Show quote
Hide quote
"Lee Derbyshire [MVP]" wrote: I have a copy of the log here now. What parts are you interested in? I'm > "MVBaker" <MVBaker@newsgroup.nospam> wrote in message > news:9225C3F4-99C5-4DD2-A6DA-7F14B5F42189@microsoft.com... > > [SNIP] > > > >> > >> It's possible that the owaauth.dll is not available to anonymous users > >> (which it needs to be, since you haven't logged in yet). Check the IIS > >> permissions, and the NTFS permissions in Explorer. The IIS log will show > >> which resource is causing the problem, and may give a more specific error > >> code. > >> > >> > >> > > > > I asked IT support and they said that NTFS permissions are Read & Execute > > and IIS permissions on the folder and the file are set correctly. Would it > > help to post more of the code from my app? Is there something in > > particular > > we can try to verify that things on the server are correct? > > > > Thanks again, > > Mike > > It would be more help at the moment to post the iis log file entries, if you > can get them? > > concerned about posting the whole log without compromizing the system... public newsgroup and all. I can see the IP address of the CEO's phone here for example ;-) Mike
Show quote
Hide quote
"MVBaker" wrote: Sorry for the double-post I intended to include this... These lines look > > > "Lee Derbyshire [MVP]" wrote: > > > "MVBaker" <MVBaker@newsgroup.nospam> wrote in message > > news:9225C3F4-99C5-4DD2-A6DA-7F14B5F42189@microsoft.com... > > > [SNIP] > > > > > >> > > >> It's possible that the owaauth.dll is not available to anonymous users > > >> (which it needs to be, since you haven't logged in yet). Check the IIS > > >> permissions, and the NTFS permissions in Explorer. The IIS log will show > > >> which resource is causing the problem, and may give a more specific error > > >> code. > > >> > > >> > > >> > > > > > > I asked IT support and they said that NTFS permissions are Read & Execute > > > and IIS permissions on the folder and the file are set correctly. Would it > > > help to post more of the code from my app? Is there something in > > > particular > > > we can try to verify that things on the server are correct? > > > > > > Thanks again, > > > Mike > > > > It would be more help at the moment to post the iis log file entries, if you > > can get them? > > > > > > I have a copy of the log here now. What parts are you interested in? I'm > concerned about posting the whole log without compromizing the system... > public newsgroup and all. I can see the IP address of the CEO's phone here > for example ;-) > > safe enough and appear to be related to the service Mike 2009-06-03 01:05:21 W3SVC1 192.168.100.6 POST /owa/auth/owaauth.dll - 443 - 192.168.100.5 - 302 0 0 2009-06-03 01:05:21 W3SVC1 192.168.100.6 SEARCH /public/processing - 443 - 192.168.100.5 Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT) 401 2 2148074254 2009-06-03 01:05:21 W3SVC1 192.168.100.6 POST /owa/auth/owaauth.dll - 443 - 192.168.100.5 - 302 0 0 2009-06-03 01:05:21 W3SVC1 192.168.100.6 SEARCH /public/processing - 443 - 192.168.100.5 Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT) 401 2 2148074254 2009-06-03 01:08:41 W3SVC1 192.168.100.6 POST /owa/auth/owaauth.dll - 443 - 192.168.100.5 - 302 0 0 2009-06-03 01:08:41 W3SVC1 192.168.100.6 SEARCH /public/processing - 443 - 192.168.100.5 Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT) 401 2 2148074254 2009-06-03 01:08:41 W3SVC1 192.168.100.6 POST /owa/auth/owaauth.dll - 443 - 192.168.100.5 - 302 0 0 2009-06-03 01:08:41 W3SVC1 192.168.100.6 SEARCH /public/processing - 443 - 192.168.100.5 Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT) 401 2 2148074254
Show quote
Hide quote
> > > After I posted this we had a conference and I pointed out that the 401 was > > > > > > > I have a copy of the log here now. What parts are you interested in? I'm > > concerned about posting the whole log without compromizing the system... > > public newsgroup and all. I can see the IP address of the CEO's phone here > > for example ;-) > > > > > Sorry for the double-post I intended to include this... These lines look > safe enough and appear to be related to the service > > Mike > > 2009-06-03 01:05:21 W3SVC1 192.168.100.6 POST /owa/auth/owaauth.dll - 443 - > 192.168.100.5 - 302 0 0 > 2009-06-03 01:05:21 W3SVC1 192.168.100.6 SEARCH /public/processing - 443 - > 192.168.100.5 Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT) 401 2 2148074254 > 2009-06-03 01:05:21 W3SVC1 192.168.100.6 POST /owa/auth/owaauth.dll - 443 - > 192.168.100.5 - 302 0 0 > 2009-06-03 01:05:21 W3SVC1 192.168.100.6 SEARCH /public/processing - 443 - > 192.168.100.5 Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT) 401 2 2148074254 > 2009-06-03 01:08:41 W3SVC1 192.168.100.6 POST /owa/auth/owaauth.dll - 443 - > 192.168.100.5 - 302 0 0 > 2009-06-03 01:08:41 W3SVC1 192.168.100.6 SEARCH /public/processing - 443 - > 192.168.100.5 Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT) 401 2 2148074254 > 2009-06-03 01:08:41 W3SVC1 192.168.100.6 POST /owa/auth/owaauth.dll - 443 - > 192.168.100.5 - 302 0 0 > 2009-06-03 01:08:41 W3SVC1 192.168.100.6 SEARCH /public/processing - 443 - > 192.168.100.5 Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT) 401 2 2148074254 > coming from the SEARCH and not from the POST to owaauth.dll. IT made permissions changes to the NTFS part of that path and things started flowing so we're set ... *almost* I thought I had something in the code for handling the _xF8FF. I remember _xF8FF being present when the email title has a / and _xF8FE for a \. Is that different in 2007? Do I use URLEncoding or UTF-8 or UTF-16? Thanks for all the help, Mike
Show quote
Hide quote
"MVBaker" <MVBaker@newsgroup.nospam> wrote in message I don't know if it's the same in E2007 or not, but the important thing is news:C868ECAB-F280-493E-B5E3-D58B508995E8@microsoft.com... >> > > >> > > >> > >> > I have a copy of the log here now. What parts are you interested in? >> > I'm >> > concerned about posting the whole log without compromizing the >> > system... >> > public newsgroup and all. I can see the IP address of the CEO's phone >> > here >> > for example ;-) >> > >> > >> Sorry for the double-post I intended to include this... These lines look >> safe enough and appear to be related to the service >> >> Mike >> >> 2009-06-03 01:05:21 W3SVC1 192.168.100.6 POST /owa/auth/owaauth.dll - >> 443 - >> 192.168.100.5 - 302 0 0 >> 2009-06-03 01:05:21 W3SVC1 192.168.100.6 SEARCH /public/processing - >> 443 - >> 192.168.100.5 Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT) 401 2 >> 2148074254 >> 2009-06-03 01:05:21 W3SVC1 192.168.100.6 POST /owa/auth/owaauth.dll - >> 443 - >> 192.168.100.5 - 302 0 0 >> 2009-06-03 01:05:21 W3SVC1 192.168.100.6 SEARCH /public/processing - >> 443 - >> 192.168.100.5 Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT) 401 2 >> 2148074254 >> 2009-06-03 01:08:41 W3SVC1 192.168.100.6 POST /owa/auth/owaauth.dll - >> 443 - >> 192.168.100.5 - 302 0 0 >> 2009-06-03 01:08:41 W3SVC1 192.168.100.6 SEARCH /public/processing - >> 443 - >> 192.168.100.5 Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT) 401 2 >> 2148074254 >> 2009-06-03 01:08:41 W3SVC1 192.168.100.6 POST /owa/auth/owaauth.dll - >> 443 - >> 192.168.100.5 - 302 0 0 >> 2009-06-03 01:08:41 W3SVC1 192.168.100.6 SEARCH /public/processing - >> 443 - >> 192.168.100.5 Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT) 401 2 >> 2148074254 >> > > After I posted this we had a conference and I pointed out that the 401 was > coming from the SEARCH and not from the POST to owaauth.dll. IT made > permissions changes to the NTFS part of that path and things started > flowing > so we're set ... *almost* > I thought I had something in the code for handling the _xF8FF. I remember > _xF8FF being present when the email title has a / and _xF8FE for a \. Is > that > different in 2007? Do I use URLEncoding or UTF-8 or UTF-16? > > Thanks for all the help, > Mike that it's best not to guess what the URL is. Your application should X-MS-ENUMATTS to get a list of attachments and their exact URLs. You should also make sure that you get auth cookies after the POST to owaauth.dll. It might help to see if the application works better if you disable FBA.
Show quote
Hide quote
> > The rest of the app does what you describe. I'm getitng the cookies from the > > After I posted this we had a conference and I pointed out that the 401 was > > coming from the SEARCH and not from the POST to owaauth.dll. IT made > > permissions changes to the NTFS part of that path and things started > > flowing > > so we're set ... *almost* > > I thought I had something in the code for handling the _xF8FF. I remember > > _xF8FF being present when the email title has a / and _xF8FE for a \. Is > > that > > different in 2007? Do I use URLEncoding or UTF-8 or UTF-16? > > > > Thanks for all the help, > > Mike > > I don't know if it's the same in E2007 or not, but the important thing is > that it's best not to guess what the URL is. Your application should > X-MS-ENUMATTS to get a list of attachments and their exact URLs. You should > also make sure that you get auth cookies after the POST to owaauth.dll. It > might help to see if the application works better if you disable FBA. > > POST response. I'm using X-MS-ENUMATTS. From that I use SelectNodes("//a:href"...) to get the href list from the emails. Some of the clients send files that are attached to emails titled something like Files for 5/29/09 and those hrefs wind up being "/public/processing/Files%20for5_xF8FF_29_xF8FF_09.EML/attfilename.zip". However when I try to grab the file using a WebRequest and that uri, the response is that the file is not found. Thanks again, Mike
Show quote
Hide quote
"MVBaker" <MVBaker@newsgroup.nospam> wrote in message There's a chance that your IIS isn't configured with a handler for .zip news:0279AE33-2B87-42C2-B091-6F6AE58B8139@microsoft.com... > >> > >> > After I posted this we had a conference and I pointed out that the 401 >> > was >> > coming from the SEARCH and not from the POST to owaauth.dll. IT made >> > permissions changes to the NTFS part of that path and things started >> > flowing >> > so we're set ... *almost* >> > I thought I had something in the code for handling the _xF8FF. I >> > remember >> > _xF8FF being present when the email title has a / and _xF8FE for a \. >> > Is >> > that >> > different in 2007? Do I use URLEncoding or UTF-8 or UTF-16? >> > >> > Thanks for all the help, >> > Mike >> >> I don't know if it's the same in E2007 or not, but the important thing is >> that it's best not to guess what the URL is. Your application should >> X-MS-ENUMATTS to get a list of attachments and their exact URLs. You >> should >> also make sure that you get auth cookies after the POST to owaauth.dll. >> It >> might help to see if the application works better if you disable FBA. >> >> > > The rest of the app does what you describe. I'm getitng the cookies from > the > POST response. I'm using X-MS-ENUMATTS. From that I use > SelectNodes("//a:href"...) to get the href list from the emails. > Some of the clients send files that are attached to emails titled > something > like Files for 5/29/09 and those hrefs wind up being > "/public/processing/Files%20for5_xF8FF_29_xF8FF_09.EML/attfilename.zip". > However when I try to grab the file using a WebRequest and that uri, the > response is that the file is not found. > > Thanks again, > Mike files. Have a look at the properties of the server, anc click in MIME Types. Make sure that .zip is there at the end of the list. Also, try to see if you can get the attachment if you copy it to a message in a mailbox. The URL format you are using is fine, provided that it is actually correct. Something else is making IIS return the 404. It may be URLScan that doesn't like those escaped characters.
Show quote
Hide quote
> > The rest of the app does what you describe. I'm getitng the cookies from I asked the IT support to check the MIME types and we did have to set one of > > the > > POST response. I'm using X-MS-ENUMATTS. From that I use > > SelectNodes("//a:href"...) to get the href list from the emails. > > Some of the clients send files that are attached to emails titled > > something > > like Files for 5/29/09 and those hrefs wind up being > > "/public/processing/Files%20for5_xF8FF_29_xF8FF_09.EML/attfilename.zip". > > However when I try to grab the file using a WebRequest and that uri, the > > response is that the file is not found. > > > > Thanks again, > > Mike > > There's a chance that your IIS isn't configured with a handler for .zip > files. Have a look at the properties of the server, anc click in MIME > Types. Make sure that .zip is there at the end of the list. Also, try to > see if you can get the attachment if you copy it to a message in a mailbox. > The URL format you are using is fine, provided that it is actually correct. > Something else is making IIS return the 404. It may be URLScan that doesn't > like those escaped characters. > > them up (and he bounced the IIS server for me). I have a test email with a single word title and a single word .zip file attached, ruling out all other variables. I still get 404 from the WebRequest for the file "https://xxxxxxxx/public/Processing/test.EML/test.zip" There's nothing I'm supposed to an href from the X-MS-ENUMATTS, right? I should have IT double check every possible permission setting on the IIS and the physical folder? Oh BTW these are emails that are in a public folder not a mailbox. But it's worked before the changeover to 2007. Mike
Show quote
Hide quote
"MVBaker" <MVBaker@newsgroup.nospam> wrote in message The URL you get from enumatts should be all you need. It's stored in a news:5A1B700F-C9FA-429F-85C8-D3276F48EA68@microsoft.com... > >> > The rest of the app does what you describe. I'm getitng the cookies >> > from >> > the >> > POST response. I'm using X-MS-ENUMATTS. From that I use >> > SelectNodes("//a:href"...) to get the href list from the emails. >> > Some of the clients send files that are attached to emails titled >> > something >> > like Files for 5/29/09 and those hrefs wind up being >> > "/public/processing/Files%20for5_xF8FF_29_xF8FF_09.EML/attfilename.zip". >> > However when I try to grab the file using a WebRequest and that uri, >> > the >> > response is that the file is not found. >> > >> > Thanks again, >> > Mike >> >> There's a chance that your IIS isn't configured with a handler for .zip >> files. Have a look at the properties of the server, anc click in MIME >> Types. Make sure that .zip is there at the end of the list. Also, try >> to >> see if you can get the attachment if you copy it to a message in a >> mailbox. >> The URL format you are using is fine, provided that it is actually >> correct. >> Something else is making IIS return the 404. It may be URLScan that >> doesn't >> like those escaped characters. >> >> > > I asked the IT support to check the MIME types and we did have to set one > of > them up (and he bounced the IIS server for me). I have a test email with a > single word title and a single word .zip file attached, ruling out all > other > variables. I still get 404 from the WebRequest for the file > > "https://xxxxxxxx/public/Processing/test.EML/test.zip" > > There's nothing I'm supposed to an href from the X-MS-ENUMATTS, right? I > should have IT double check every possible permission setting on the IIS > and > the physical folder? > Oh BTW these are emails that are in a public folder not a mailbox. But > it's > worked before the changeover to 2007. > > Mike nicely encoded format. I know that GET still works for attachments in E2007 because I'm doing the same as you, and it has always worked fine for me. I just checked, and it still works. The only thing I do different is setting the Translate:f header, and I can't see that in your code. What happens if you type the URL into a browser address bar? Do you still get a 404 error?
Show quote
Hide quote
"Lee Derbyshire [MVP]" wrote: Yes I get a 404 when I type that url into the address bar. I tried a couple > "MVBaker" <MVBaker@newsgroup.nospam> wrote in message > news:5A1B700F-C9FA-429F-85C8-D3276F48EA68@microsoft.com... > > > >> > The rest of the app does what you describe. I'm getitng the cookies > >> > from > >> > the > >> > POST response. I'm using X-MS-ENUMATTS. From that I use > >> > SelectNodes("//a:href"...) to get the href list from the emails. > >> > Some of the clients send files that are attached to emails titled > >> > something > >> > like Files for 5/29/09 and those hrefs wind up being > >> > "/public/processing/Files%20for5_xF8FF_29_xF8FF_09.EML/attfilename.zip". > >> > However when I try to grab the file using a WebRequest and that uri, > >> > the > >> > response is that the file is not found. > >> > > >> > Thanks again, > >> > Mike > >> > >> There's a chance that your IIS isn't configured with a handler for .zip > >> files. Have a look at the properties of the server, anc click in MIME > >> Types. Make sure that .zip is there at the end of the list. Also, try > >> to > >> see if you can get the attachment if you copy it to a message in a > >> mailbox. > >> The URL format you are using is fine, provided that it is actually > >> correct. > >> Something else is making IIS return the 404. It may be URLScan that > >> doesn't > >> like those escaped characters. > >> > >> > > > > I asked the IT support to check the MIME types and we did have to set one > > of > > them up (and he bounced the IIS server for me). I have a test email with a > > single word title and a single word .zip file attached, ruling out all > > other > > variables. I still get 404 from the WebRequest for the file > > > > "https://xxxxxxxx/public/Processing/test.EML/test.zip" > > > > There's nothing I'm supposed to an href from the X-MS-ENUMATTS, right? I > > should have IT double check every possible permission setting on the IIS > > and > > the physical folder? > > Oh BTW these are emails that are in a public folder not a mailbox. But > > it's > > worked before the changeover to 2007. > > > > Mike > > The URL you get from enumatts should be all you need. It's stored in a > nicely encoded format. I know that GET still works for attachments in E2007 > because I'm doing the same as you, and it has always worked fine for me. I > just checked, and it still works. The only thing I do different is setting > the Translate:f header, and I can't see that in your code. > > What happens if you type the URL into a browser address bar? Do you still > get a 404 error? > > different things... with server/owa/public/processing/test.EML/test.zip I also get a 404 but with server/exchange/public/processing/test.EML/test.zip I get a login dialog box. My credentials won't let me get in. The appearance of the login dialog would mean that it found a file for which it needs authorization, correct? (I'm sending this info to IT) Mike
Show quote
Hide quote
"MVBaker" <MVBaker@newsgroup.nospam> wrote in message These may be just typos, but...news:2B3574B5-E9A7-4AC4-9323-3501AEBFCB96@microsoft.com... > > > "Lee Derbyshire [MVP]" wrote: > >> "MVBaker" <MVBaker@newsgroup.nospam> wrote in message >> news:5A1B700F-C9FA-429F-85C8-D3276F48EA68@microsoft.com... >> > >> >> > The rest of the app does what you describe. I'm getitng the cookies >> >> > from >> >> > the >> >> > POST response. I'm using X-MS-ENUMATTS. From that I use >> >> > SelectNodes("//a:href"...) to get the href list from the emails. >> >> > Some of the clients send files that are attached to emails titled >> >> > something >> >> > like Files for 5/29/09 and those hrefs wind up being >> >> > "/public/processing/Files%20for5_xF8FF_29_xF8FF_09.EML/attfilename.zip". >> >> > However when I try to grab the file using a WebRequest and that uri, >> >> > the >> >> > response is that the file is not found. >> >> > >> >> > Thanks again, >> >> > Mike >> >> >> >> There's a chance that your IIS isn't configured with a handler for >> >> .zip >> >> files. Have a look at the properties of the server, anc click in MIME >> >> Types. Make sure that .zip is there at the end of the list. Also, >> >> try >> >> to >> >> see if you can get the attachment if you copy it to a message in a >> >> mailbox. >> >> The URL format you are using is fine, provided that it is actually >> >> correct. >> >> Something else is making IIS return the 404. It may be URLScan that >> >> doesn't >> >> like those escaped characters. >> >> >> >> >> > >> > I asked the IT support to check the MIME types and we did have to set >> > one >> > of >> > them up (and he bounced the IIS server for me). I have a test email >> > with a >> > single word title and a single word .zip file attached, ruling out all >> > other >> > variables. I still get 404 from the WebRequest for the file >> > >> > "https://xxxxxxxx/public/Processing/test.EML/test.zip" >> > >> > There's nothing I'm supposed to an href from the X-MS-ENUMATTS, right? >> > I >> > should have IT double check every possible permission setting on the >> > IIS >> > and >> > the physical folder? >> > Oh BTW these are emails that are in a public folder not a mailbox. But >> > it's >> > worked before the changeover to 2007. >> > >> > Mike >> >> The URL you get from enumatts should be all you need. It's stored in a >> nicely encoded format. I know that GET still works for attachments in >> E2007 >> because I'm doing the same as you, and it has always worked fine for me. >> I >> just checked, and it still works. The only thing I do different is >> setting >> the Translate:f header, and I can't see that in your code. >> >> What happens if you type the URL into a browser address bar? Do you >> still >> get a 404 error? >> >> > > Yes I get a 404 when I type that url into the address bar. I tried a > couple > different things... with server/owa/public/processing/test.EML/test.zip I > also get a 404 but with > server/exchange/public/processing/test.EML/test.zip I > get a login dialog box. My credentials won't let me get in. The appearance > of > the login dialog would mean that it found a file for which it needs > authorization, correct? (I'm sending this info to IT) > > Mike server/owa/public/processing/test.EML/test.zip will not work, because the OWA Vdir doesn't map in the same way that ExIFS does. If the server does not have the CAS role, that may explain the 404, since there will not be an OWA VDir. server/exchange/public/processing/test.EML/test.zip will not work because /public is not a subdirectory of /exchange Did you try: server/public/processing/test.EML/test.zip ? I assume that 'server' is the name of an MBX server that actually has the PF database homed on it, and not just a CAS server?
Show quote
Hide quote
> > Yes I get a 404 when I type that url into the address bar. I tried a Thanks for your patience. These weren't typos, that was me grasping at > > couple > > different things... with server/owa/public/processing/test.EML/test.zip I > > also get a 404 but with > > server/exchange/public/processing/test.EML/test.zip I > > get a login dialog box. My credentials won't let me get in. The appearance > > of > > the login dialog would mean that it found a file for which it needs > > authorization, correct? (I'm sending this info to IT) > > > > Mike > > These may be just typos, but... > > server/owa/public/processing/test.EML/test.zip > will not work, because the OWA Vdir doesn't map in the same way that ExIFS > does. If the server does not have the CAS role, that may explain the 404, > since there will not be an OWA VDir. > > server/exchange/public/processing/test.EML/test.zip > will not work because /public is not a subdirectory of /exchange > > Did you try: > server/public/processing/test.EML/test.zip > ? I assume that 'server' is the name of an MBX server that actually has the > PF database homed on it, and not just a CAS server? > > straws trying to hit on where the file was by educated guess. I forwarded your response to the IT support office. I didn't want to clutter this up with a lot of code but I've run out of other ideas so I posted the test page code that I'm using to debug this mess below. I removed the non-sense debug outputs and boiled it down to just what's necessary... You'll probably recognize it as Henning Krause, Dan's WebDav, Glen Scales, and you. The only reason this is not done in EWS is that it was already written to run with Ex2003 and I was hoping that making it work with 2007 would be quicker and we could add a re-write to the schedule down the line.. Protected Sub btnHttpWebRequest_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnHttpWebRequest.Click GetEmailsFromFolder("/public/processing/") End Sub Sub GetEmailsFromFolder(ByVal strFolder As String) Dim sBaseUri As String = "https://office.servername.com" + strFolder Dim sLoginID As String = "TheUser" Dim sDomain As String = "THEDOMAIN" Dim sPassword As String = "ThePassword" Dim cookies As CookieCollection Dim strQuery As String Dim nsmgr As System.Xml.XmlNamespaceManager '"<D:sql>SELECT *" & _ strQuery = "<?xml version=""1.0""?>" & _ "<D:searchrequest xmlns:D = ""DAV:"" >" & _ "<D:sql>SELECT ""http://schemas.microsoft.com/exchange/outlookmessageclass""" & _ ", ""DAV:href"", ""DAV:fromemail"", ""DAV:displayname""" & _ " FROM scope('shallow traversal of """ & _ sBaseUri & """ ')" strQuery = strQuery & " ORDER BY ""urn:schemas:httpmail:datereceived"" DESC" strQuery = strQuery & "</D:sql></D:searchrequest>" Dim oCredentialCache As CredentialCache = New CredentialCache() Dim oCredentials As NetworkCredential = New NetworkCredential(sLoginID, sPassword, sDomain) oCredentialCache.Add(New Uri(sBaseUri), "NTLM", oCredentials) Dim encoding As ASCIIEncoding = New ASCIIEncoding() Dim bQuery As Byte() = encoding.GetBytes(strQuery) cookies = AuthenticateSecureOWA("office.servername.com", sDomain, sLoginID, sPassword) Dim oRequest As HttpWebRequest = CType(HttpWebRequest.Create(New Uri(sBaseUri)), HttpWebRequest) oRequest.CookieContainer = New CookieContainer() oRequest.CookieContainer.Add(cookies) oRequest.Method = "SEARCH" oRequest.ContentType = "text/xml" oRequest.Timeout = 60000 oRequest.ContentLength = bQuery.Length oRequest.Credentials = oCredentialCache oRequest.Headers.Add("Depth", "0") oRequest.Headers.Add("Translate", "f") oRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT)" ' use a stream to write the query into the bytearray format Dim newStream As System.IO.Stream = oRequest.GetRequestStream() newStream.Write(bQuery, 0, bQuery.Length) newStream.Close() Dim oResponse As HttpWebResponse = CType(oRequest.GetResponse(), HttpWebResponse) Dim responseStream As System.IO.Stream = oResponse.GetResponseStream() ' get an xmlDoc from the stream Dim xmlDoc As XmlDocument = New XmlDocument() xmlDoc.Load(responseStream) ' Create a new XmlNamespaceManager. nsmgr = New System.Xml.XmlNamespaceManager(xmlDoc.NameTable) nsmgr.AddNamespace("a", "DAV:") nsmgr.AddNamespace("d", "http://schemas.microsoft.com/exchange/") ' get the list of responses from the docnsmgr.AddNamespace("p", "http://schemas.microsoft.com/mapi/proptag/") Dim xmlResponses As XmlNodeList xmlResponses = xmlDoc.SelectNodes("a:multistatus/a:response", nsmgr) For Each xmlnodeResponse As XmlNode In xmlResponses ProcessResponse(xmlnodeResponse, nsmgr, oCredentialCache, cookies) Next responseStream.Close() oResponse.Close() End Sub Private Function AuthenticateSecureOWA(ByVal strServerName As String, ByVal strDomain As String, ByVal strUserName As String, ByVal strPassword As String) As CookieCollection Dim AuthURL As System.Uri Dim CookieJar As CookieContainer Try ' Construct our destination URI. AuthURL = New System.Uri("https://" + strServerName + "/owa/auth/owaauth.dll") Catch ex As Exception MsgBox("Error occurred while you are creating the URI for OWA authentication!" + vbCrLf + vbCrLf + ex.Message) Return Nothing End Try Dim WebReq As HttpWebRequest CookieJar = New CookieContainer ' Create our request object for the constructed URI. WebReq = CType(WebRequest.Create(AuthURL), HttpWebRequest) WebReq.CookieContainer = CookieJar ' Create our post data string that is required by OWA (owaauth.dll). Dim strPostFields As String = "destination=https%3A%2F%2F" & strServerName & "%2FExchange%2F" + strUserName + "%2F&username=" + strDomain + "%5C" + strUserName + "&password=" + strPassword + "&SubmitCreds=LogOn" WebReq.KeepAlive = True WebReq.Expect = "" WebReq.Accept = "*/*" WebReq.AllowAutoRedirect = False WebReq.Method = "POST" ' Store the post data into a byte array. Dim PostData() As Byte = System.Text.Encoding.ASCII.GetBytes(strPostFields) ' Set the content length. WebReq.ContentLength = PostData.Length Dim tmpStream As Stream Try ' Create a request stream. Write the post data to the stream. tmpStream = WebReq.GetRequestStream() tmpStream.Write(PostData, 0, PostData.Length) tmpStream.Close() Catch ex As Exception MsgBox("Error occurred while trying OWA authentication!" + vbCrLf + vbCrLf + ex.Message) Return Nothing End Try ' Get the response from the request. Dim WebResp As HttpWebResponse = WebReq.GetResponse() ' Create a stream to capture the response data Dim tmpStreamRead As New StreamReader(WebResp.GetResponseStream()) ' Write returned data to a string. Dim strResponseData As String = tmpStreamRead.ReadToEnd() tmpStreamRead.Close() ' Close the response object. WebResp.Close() ' Get our returned cookie set. Return WebResp.Cookies End Function Private Function ProcessResponse(ByVal xmlnodeResponse As XmlNode, _ ByVal nsmgr As XmlNamespaceManager, _ ByRef credCache As CredentialCache, _ ByRef cookies As CookieCollection) As Boolean Dim xmlNodeHref As XmlNode Dim xmlNodePropStats As XmlNodeList Dim xmlNodeProp As XmlNode Dim xmlNodeStatus As XmlNode Dim xmlNodeMsgClass As XmlNode Dim strMsgType As String = "" Dim strEmailName As String = "" xmlNodeHref = xmlnodeResponse.SelectSingleNode("a:href", nsmgr) If xmlNodeHref IsNot Nothing Then strEmailName = xmlNodeHref.InnerText End If If strEmailName.EndsWith("/") Then Return False End If xmlNodePropStats = xmlnodeResponse.SelectNodes("a:propstat", nsmgr) For Each xmlNodeProp In xmlNodePropStats xmlNodeStatus = xmlNodeProp.SelectSingleNode("a:status", nsmgr) If (xmlNodeStatus.InnerText = "HTTP/1.1 200 OK") Then Debug.Print("Status OK") xmlNodeMsgClass = xmlNodeProp.SelectSingleNode("a:prop/d:outlookmessageclass", nsmgr) Debug.Print(xmlNodeMsgClass.InnerText) strMsgType = xmlNodeMsgClass.InnerText End If Next If strEmailName <> "" AndAlso strMsgType <> "" Then GetAttachments(strEmailName, credCache, cookies) End If Return True End Function Private Function GetAttachments(ByVal strEmailName As String, _ ByRef credCache As CredentialCache, _ ByRef cookies As CookieCollection) As Boolean '************************* PROCESS ONE EMAIL FOR THE ATTACHMENTS Dim Request As HttpWebRequest Dim Response As HttpWebResponse Dim ResponseXmlDoc As System.Xml.XmlDocument Dim root As System.Xml.XmlNode Dim nsmgr As System.Xml.XmlNamespaceManager Dim InnerPropstatNodes As System.Xml.XmlNodeList Dim HrefNodes As System.Xml.XmlNodeList Dim InnerStatusNode As System.Xml.XmlNode Dim InnerPropNode As System.Xml.XmlNode Request = CType(HttpWebRequest.Create(New Uri(strEmailName)), HttpWebRequest) Request.CookieContainer = New CookieContainer() Request.CookieContainer.Add(cookies) Request.Credentials = credCache Request.Method = "X-MS-ENUMATTS" Response = CType(Request.GetResponse(), System.Net.HttpWebResponse) Dim responseStream As System.IO.Stream = Response.GetResponseStream() ResponseXmlDoc = New System.Xml.XmlDocument ResponseXmlDoc.Load(responseStream) root = ResponseXmlDoc.DocumentElement nsmgr = New System.Xml.XmlNamespaceManager(ResponseXmlDoc.NameTable) nsmgr.AddNamespace("a", "DAV:") nsmgr.AddNamespace("d", "http://schemas.microsoft.com/mapi/proptag/") nsmgr.AddNamespace("e", "urn:schemas:httpmail:")' 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). InnerPropstatNodes = 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 Then ' Iterate through the attachment properties. Dim i As Integer For i = 0 To HrefNodes.Count - 1 ' Use an XPath query to get the DAV:status node from the DAV:propstat node. InnerStatusNode = InnerPropstatNodes(i).SelectSingleNode("a:status", nsmgr) ' Check the status of the attachment properties. If Not InnerStatusNode.InnerText = "HTTP/1.1 200 OK" Then Debug.Print("Attachment: " & HrefNodes(i).InnerText) Debug.Print("Status: " & InnerStatusNode.InnerText) Debug.Print("") Else ' get the actual full name of the file InnerPropNode = InnerPropstatNodes(i).SelectSingleNode("a:prop/e:attachmentfilename", nsmgr) If InnerPropNode IsNot Nothing Then Debug.Print("Attachment filename: " & InnerPropNode.InnerText) End If Dim reqAttRequest As HttpWebRequest Dim resAttResponse As HttpWebResponse reqAttRequest = WebRequest.Create(HrefNodes(i).InnerText) Try reqAttRequest.Method = "GET" reqAttRequest.CookieContainer = New CookieContainer() reqAttRequest.CookieContainer.Add(cookies) reqAttRequest.Credentials = credCache resAttResponse = reqAttRequest.GetResponse() Dim instream As Stream = resAttResponse.GetResponseStream() Dim outStream As New FileStream("C:\" & InnerPropNode.InnerText, FileMode.Create) Dim buffer(8192) As Byte Dim intBytesRead As Integer Do intBytesRead = instream.Read(buffer, 0, buffer.Length) If (intBytesRead = 0) Then Exit Do End If outStream.Write(buffer, 0, intBytesRead) Loop While intBytesRead > 0 outStream.Close() resAttResponse.Close() Catch ex As Exception Debug.Print(ex.Message) End Try End If Next Else Debug.Print("No attachments found.") End If ' Clean up. responseStream.Close() Response.Close() End Function Greetings,
I work in IT support where Mike is trying to implement his application. If there is anything you need from me in order to solve this please let me know. I have a feeling the issue resides on the server config but I'm not sure what needs to change. To answer your earlier question Lee, the machine named 'server' previously mentioned in the MBX server that has the public folder database on it and is not just a CAS server. Thanks for your help! Matt Show quoteHide quote "MVBaker" wrote: > > > > Yes I get a 404 when I type that url into the address bar. I tried a > > > couple > > > different things... with server/owa/public/processing/test.EML/test.zip I > > > also get a 404 but with > > > server/exchange/public/processing/test.EML/test.zip I > > > get a login dialog box. My credentials won't let me get in. The appearance > > > of > > > the login dialog would mean that it found a file for which it needs > > > authorization, correct? (I'm sending this info to IT) > > > > > > Mike > > > > These may be just typos, but... > > > > server/owa/public/processing/test.EML/test.zip > > will not work, because the OWA Vdir doesn't map in the same way that ExIFS > > does. If the server does not have the CAS role, that may explain the 404, > > since there will not be an OWA VDir. > > > > server/exchange/public/processing/test.EML/test.zip > > will not work because /public is not a subdirectory of /exchange > > > > Did you try: > > server/public/processing/test.EML/test.zip > > ? I assume that 'server' is the name of an MBX server that actually has the > > PF database homed on it, and not just a CAS server? > > > > > > Thanks for your patience. These weren't typos, that was me grasping at > straws trying to hit on where the file was by educated guess. I forwarded > your response to the IT support office. I didn't want to clutter this up with > a lot of code but I've run out of other ideas so I posted the test page code > that I'm using to debug this mess below. I removed the non-sense debug > outputs and boiled it down to just what's necessary... You'll probably > recognize it as Henning Krause, Dan's WebDav, Glen Scales, and you. > The only reason this is not done in EWS is that it was already written to > run with Ex2003 and I was hoping that making it work with 2007 would be > quicker and we could add a re-write to the schedule down the line.. > > Protected Sub btnHttpWebRequest_Click(ByVal sender As Object, ByVal e As > EventArgs) Handles btnHttpWebRequest.Click > GetEmailsFromFolder("/public/processing/") > End Sub > > Sub GetEmailsFromFolder(ByVal strFolder As String) > > Dim sBaseUri As String = "https://office.servername.com" + strFolder > Dim sLoginID As String = "TheUser" > Dim sDomain As String = "THEDOMAIN" > Dim sPassword As String = "ThePassword" > Dim cookies As CookieCollection > Dim strQuery As String > Dim nsmgr As System.Xml.XmlNamespaceManager > > '"<D:sql>SELECT *" & _ > strQuery = "<?xml version=""1.0""?>" & _ > "<D:searchrequest xmlns:D = ""DAV:"" >" & _ > "<D:sql>SELECT > ""http://schemas.microsoft.com/exchange/outlookmessageclass""" & _ > ", ""DAV:href"", ""DAV:fromemail"", > ""DAV:displayname""" & _ > " FROM scope('shallow traversal of """ & _ > sBaseUri & """ ')" > strQuery = strQuery & " ORDER BY ""urn:schemas:httpmail:datereceived"" > DESC" > strQuery = strQuery & "</D:sql></D:searchrequest>" > > Dim oCredentialCache As CredentialCache = New CredentialCache() > Dim oCredentials As NetworkCredential = New NetworkCredential(sLoginID, > sPassword, sDomain) > oCredentialCache.Add(New Uri(sBaseUri), "NTLM", oCredentials) > > Dim encoding As ASCIIEncoding = New ASCIIEncoding() > Dim bQuery As Byte() = encoding.GetBytes(strQuery) > > cookies = AuthenticateSecureOWA("office.servername.com", sDomain, > sLoginID, sPassword) > > Dim oRequest As HttpWebRequest = CType(HttpWebRequest.Create(New > Uri(sBaseUri)), HttpWebRequest) > oRequest.CookieContainer = New CookieContainer() > oRequest.CookieContainer.Add(cookies) > > oRequest.Method = "SEARCH" > oRequest.ContentType = "text/xml" > oRequest.Timeout = 60000 > oRequest.ContentLength = bQuery.Length > oRequest.Credentials = oCredentialCache > oRequest.Headers.Add("Depth", "0") > oRequest.Headers.Add("Translate", "f") > oRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT)" > > ' use a stream to write the query into the bytearray format > Dim newStream As System.IO.Stream = oRequest.GetRequestStream() > newStream.Write(bQuery, 0, bQuery.Length) > newStream.Close() > > Dim oResponse As HttpWebResponse = CType(oRequest.GetResponse(), > HttpWebResponse) > Dim responseStream As System.IO.Stream = oResponse.GetResponseStream() > > ' get an xmlDoc from the stream > Dim xmlDoc As XmlDocument = New XmlDocument() > xmlDoc.Load(responseStream) > > ' Create a new XmlNamespaceManager. > nsmgr = New System.Xml.XmlNamespaceManager(xmlDoc.NameTable) > nsmgr.AddNamespace("a", "DAV:") > nsmgr.AddNamespace("d", "http://schemas.microsoft.com/exchange/") > nsmgr.AddNamespace("p", "http://schemas.microsoft.com/mapi/proptag/") > > ' get the list of responses from the doc > Dim xmlResponses As XmlNodeList > xmlResponses = xmlDoc.SelectNodes("a:multistatus/a:response", nsmgr) > > For Each xmlnodeResponse As XmlNode In xmlResponses > ProcessResponse(xmlnodeResponse, nsmgr, oCredentialCache, cookies) > Next > > responseStream.Close() > oResponse.Close() > > End Sub > > Private Function AuthenticateSecureOWA(ByVal strServerName As String, ByVal > strDomain As String, ByVal strUserName As String, ByVal strPassword As > String) As CookieCollection > Dim AuthURL As System.Uri > Dim CookieJar As CookieContainer > Try > ' Construct our destination URI. > AuthURL = New System.Uri("https://" + strServerName + > "/owa/auth/owaauth.dll") > Catch ex As Exception > MsgBox("Error occurred while you are creating the URI for OWA > authentication!" + vbCrLf + vbCrLf + ex.Message) > Return Nothing > End Try > Dim WebReq As HttpWebRequest > CookieJar = New CookieContainer > ' Create our request object for the constructed URI. > WebReq = CType(WebRequest.Create(AuthURL), HttpWebRequest) > WebReq.CookieContainer = CookieJar > ' Create our post data string that is required by OWA (owaauth.dll). > Dim strPostFields As String = "destination=https%3A%2F%2F" & > strServerName & "%2FExchange%2F" + strUserName + "%2F&username=" + strDomain > + "%5C" + strUserName + "&password=" + strPassword + "&SubmitCreds=LogOn" > WebReq.KeepAlive = True > WebReq.Expect = "" > WebReq.Accept = "*/*" > WebReq.AllowAutoRedirect = False > WebReq.Method = "POST" > ' Store the post data into a byte array. > Dim PostData() As Byte = > System.Text.Encoding.ASCII.GetBytes(strPostFields) > ' Set the content length. > WebReq.ContentLength = PostData.Length > Dim tmpStream As Stream > Try > ' Create a request stream. Write the post data to the stream. > tmpStream = WebReq.GetRequestStream() > tmpStream.Write(PostData, 0, PostData.Length) > tmpStream.Close() > Catch ex As Exception > MsgBox("Error occurred while trying OWA authentication!" + vbCrLf + > vbCrLf + ex.Message) > Return Nothing > End Try > ' Get the response from the request. > Dim WebResp As HttpWebResponse = WebReq.GetResponse() > ' Create a stream to capture the response data > Dim tmpStreamRead As New StreamReader(WebResp.GetResponseStream()) > ' Write returned data to a string. > Dim strResponseData As String = tmpStreamRead.ReadToEnd() > tmpStreamRead.Close() > ' Close the response object. > WebResp.Close() > ' Get our returned cookie set. > Return WebResp.Cookies > > End Function > > Private Function ProcessResponse(ByVal xmlnodeResponse As XmlNode, _ > ByVal nsmgr As XmlNamespaceManager, _ > ByRef credCache As CredentialCache, _ > ByRef cookies As CookieCollection) As Boolean > Dim xmlNodeHref As XmlNode > Dim xmlNodePropStats As XmlNodeList > Dim xmlNodeProp As XmlNode > Dim xmlNodeStatus As XmlNode > Dim xmlNodeMsgClass As XmlNode > Dim strMsgType As String = "" > Dim strEmailName As String = "" > > xmlNodeHref = xmlnodeResponse.SelectSingleNode("a:href", nsmgr) > If xmlNodeHref IsNot Nothing Then > strEmailName = xmlNodeHref.InnerText > End If > If strEmailName.EndsWith("/") Then > Return False > End If > xmlNodePropStats = xmlnodeResponse.SelectNodes("a:propstat", nsmgr) > For Each xmlNodeProp In xmlNodePropStats > xmlNodeStatus = xmlNodeProp.SelectSingleNode("a:status", nsmgr) > If (xmlNodeStatus.InnerText = "HTTP/1.1 200 OK") Then > Debug.Print("Status OK") > xmlNodeMsgClass = > xmlNodeProp.SelectSingleNode("a:prop/d:outlookmessageclass", nsmgr) > Debug.Print(xmlNodeMsgClass.InnerText) > strMsgType = xmlNodeMsgClass.InnerText > End If > Next > If strEmailName <> "" AndAlso strMsgType <> "" Then > GetAttachments(strEmailName, credCache, cookies) > End If > Return True > > End Function > > Private Function GetAttachments(ByVal strEmailName As String, _ > ByRef credCache As CredentialCache, _ > ByRef cookies As CookieCollection) As Boolean > > '************************* PROCESS ONE EMAIL FOR THE ATTACHMENTS > Dim Request As HttpWebRequest > Dim Response As HttpWebResponse > Dim ResponseXmlDoc As System.Xml.XmlDocument > Dim root As System.Xml.XmlNode > Dim nsmgr As System.Xml.XmlNamespaceManager > Dim InnerPropstatNodes As System.Xml.XmlNodeList > Dim HrefNodes As System.Xml.XmlNodeList > Dim InnerStatusNode As System.Xml.XmlNode > Dim InnerPropNode As System.Xml.XmlNode > > Request = CType(HttpWebRequest.Create(New Uri(strEmailName)), > HttpWebRequest) > Request.CookieContainer = New CookieContainer() > Request.CookieContainer.Add(cookies) > Request.Credentials = credCache > > Request.Method = "X-MS-ENUMATTS" > Response = CType(Request.GetResponse(), System.Net.HttpWebResponse) > Dim responseStream As System.IO.Stream = Response.GetResponseStream() > ResponseXmlDoc = New System.Xml.XmlDocument > ResponseXmlDoc.Load(responseStream) > root = ResponseXmlDoc.DocumentElement > nsmgr = New System.Xml.XmlNamespaceManager(ResponseXmlDoc.NameTable) > > nsmgr.AddNamespace("a", "DAV:") > nsmgr.AddNamespace("d", "http://schemas.microsoft.com/mapi/proptag/") > nsmgr.AddNamespace("e", "urn:schemas:httpmail:") > nsmgr.AddNamespace("n0", "http://schemas.microsoft.com/exchange/") > > ' 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). > InnerPropstatNodes = 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 Then > ' Iterate through the attachment properties. > Dim i As Integer > For i = 0 To HrefNodes.Count - 1 > > ' Use an XPath query to get the DAV:status node from the > DAV:propstat node. > InnerStatusNode = > InnerPropstatNodes(i).SelectSingleNode("a:status", nsmgr) > > ' Check the status of the attachment properties. > If Not InnerStatusNode.InnerText = "HTTP/1.1 200 OK" Then > Debug.Print("Attachment: " & HrefNodes(i).InnerText) > Debug.Print("Status: " & InnerStatusNode.InnerText) > Debug.Print("") > > Else > > ' get the actual full name of the file > InnerPropNode = > InnerPropstatNodes(i).SelectSingleNode("a:prop/e:attachmentfilename", nsmgr) > If InnerPropNode IsNot Nothing Then > Debug.Print("Attachment filename: " & > InnerPropNode.InnerText) > End If > > Dim reqAttRequest As HttpWebRequest > Dim resAttResponse As HttpWebResponse > reqAttRequest = WebRequest.Create(HrefNodes(i).InnerText) > Try > reqAttRequest.Method = "GET" > reqAttRequest.CookieContainer = New CookieContainer() > reqAttRequest.CookieContainer.Add(cookies) > reqAttRequest.Credentials = credCache The code seems to assume that FBA is required on your public VDir. Have you
made sure that it is? Also, if it is, add some code to display the cookies that are returned after the owaauth post. Make sure that you get cookies named sessionid and cadata. Show quoteHide quote "MVBaker" <MVBaker@newsgroup.nospam> wrote in message news:E3E666B8-DF9F-42CE-82EA-731BEE1C05F0@microsoft.com... > >> > Yes I get a 404 when I type that url into the address bar. I tried a >> > couple >> > different things... with server/owa/public/processing/test.EML/test.zip >> > I >> > also get a 404 but with >> > server/exchange/public/processing/test.EML/test.zip I >> > get a login dialog box. My credentials won't let me get in. The >> > appearance >> > of >> > the login dialog would mean that it found a file for which it needs >> > authorization, correct? (I'm sending this info to IT) >> > >> > Mike >> >> These may be just typos, but... >> >> server/owa/public/processing/test.EML/test.zip >> will not work, because the OWA Vdir doesn't map in the same way that >> ExIFS >> does. If the server does not have the CAS role, that may explain the >> 404, >> since there will not be an OWA VDir. >> >> server/exchange/public/processing/test.EML/test.zip >> will not work because /public is not a subdirectory of /exchange >> >> Did you try: >> server/public/processing/test.EML/test.zip >> ? I assume that 'server' is the name of an MBX server that actually has >> the >> PF database homed on it, and not just a CAS server? >> >> > > Thanks for your patience. These weren't typos, that was me grasping at > straws trying to hit on where the file was by educated guess. I forwarded > your response to the IT support office. I didn't want to clutter this up > with > a lot of code but I've run out of other ideas so I posted the test page > code > that I'm using to debug this mess below. I removed the non-sense debug > outputs and boiled it down to just what's necessary... You'll probably > recognize it as Henning Krause, Dan's WebDav, Glen Scales, and you. > The only reason this is not done in EWS is that it was already written to > run with Ex2003 and I was hoping that making it work with 2007 would be > quicker and we could add a re-write to the schedule down the line.. > > Protected Sub btnHttpWebRequest_Click(ByVal sender As Object, ByVal e As > EventArgs) Handles btnHttpWebRequest.Click > GetEmailsFromFolder("/public/processing/") > End Sub > > Sub GetEmailsFromFolder(ByVal strFolder As String) > > Dim sBaseUri As String = "https://office.servername.com" + strFolder > Dim sLoginID As String = "TheUser" > Dim sDomain As String = "THEDOMAIN" > Dim sPassword As String = "ThePassword" > Dim cookies As CookieCollection > Dim strQuery As String > Dim nsmgr As System.Xml.XmlNamespaceManager > > '"<D:sql>SELECT *" & _ > strQuery = "<?xml version=""1.0""?>" & _ > "<D:searchrequest xmlns:D = ""DAV:"" >" & _ > "<D:sql>SELECT > ""http://schemas.microsoft.com/exchange/outlookmessageclass""" & _ > ", ""DAV:href"", ""DAV:fromemail"", > ""DAV:displayname""" & _ > " FROM scope('shallow traversal of """ & _ > sBaseUri & """ ')" > strQuery = strQuery & " ORDER BY ""urn:schemas:httpmail:datereceived"" > DESC" > strQuery = strQuery & "</D:sql></D:searchrequest>" > > Dim oCredentialCache As CredentialCache = New CredentialCache() > Dim oCredentials As NetworkCredential = New NetworkCredential(sLoginID, > sPassword, sDomain) > oCredentialCache.Add(New Uri(sBaseUri), "NTLM", oCredentials) > > Dim encoding As ASCIIEncoding = New ASCIIEncoding() > Dim bQuery As Byte() = encoding.GetBytes(strQuery) > > cookies = AuthenticateSecureOWA("office.servername.com", sDomain, > sLoginID, sPassword) > > Dim oRequest As HttpWebRequest = CType(HttpWebRequest.Create(New > Uri(sBaseUri)), HttpWebRequest) > oRequest.CookieContainer = New CookieContainer() > oRequest.CookieContainer.Add(cookies) > > oRequest.Method = "SEARCH" > oRequest.ContentType = "text/xml" > oRequest.Timeout = 60000 > oRequest.ContentLength = bQuery.Length > oRequest.Credentials = oCredentialCache > oRequest.Headers.Add("Depth", "0") > oRequest.Headers.Add("Translate", "f") > oRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT)" > > ' use a stream to write the query into the bytearray format > Dim newStream As System.IO.Stream = oRequest.GetRequestStream() > newStream.Write(bQuery, 0, bQuery.Length) > newStream.Close() > > Dim oResponse As HttpWebResponse = CType(oRequest.GetResponse(), > HttpWebResponse) > Dim responseStream As System.IO.Stream = oResponse.GetResponseStream() > > ' get an xmlDoc from the stream > Dim xmlDoc As XmlDocument = New XmlDocument() > xmlDoc.Load(responseStream) > > ' Create a new XmlNamespaceManager. > nsmgr = New System.Xml.XmlNamespaceManager(xmlDoc.NameTable) > nsmgr.AddNamespace("a", "DAV:") > nsmgr.AddNamespace("d", "http://schemas.microsoft.com/exchange/") > nsmgr.AddNamespace("p", "http://schemas.microsoft.com/mapi/proptag/") > > ' get the list of responses from the doc > Dim xmlResponses As XmlNodeList > xmlResponses = xmlDoc.SelectNodes("a:multistatus/a:response", nsmgr) > > For Each xmlnodeResponse As XmlNode In xmlResponses > ProcessResponse(xmlnodeResponse, nsmgr, oCredentialCache, cookies) > Next > > responseStream.Close() > oResponse.Close() > > End Sub > > Private Function AuthenticateSecureOWA(ByVal strServerName As String, > ByVal > strDomain As String, ByVal strUserName As String, ByVal strPassword As > String) As CookieCollection > Dim AuthURL As System.Uri > Dim CookieJar As CookieContainer > Try > ' Construct our destination URI. > AuthURL = New System.Uri("https://" + strServerName + > "/owa/auth/owaauth.dll") > Catch ex As Exception > MsgBox("Error occurred while you are creating the URI for OWA > authentication!" + vbCrLf + vbCrLf + ex.Message) > Return Nothing > End Try > Dim WebReq As HttpWebRequest > CookieJar = New CookieContainer > ' Create our request object for the constructed URI. > WebReq = CType(WebRequest.Create(AuthURL), HttpWebRequest) > WebReq.CookieContainer = CookieJar > ' Create our post data string that is required by OWA (owaauth.dll). > Dim strPostFields As String = "destination=https%3A%2F%2F" & > strServerName & "%2FExchange%2F" + strUserName + "%2F&username=" + > strDomain > + "%5C" + strUserName + "&password=" + strPassword + "&SubmitCreds=LogOn" > WebReq.KeepAlive = True > WebReq.Expect = "" > WebReq.Accept = "*/*" > WebReq.AllowAutoRedirect = False > WebReq.Method = "POST" > ' Store the post data into a byte array. > Dim PostData() As Byte = > System.Text.Encoding.ASCII.GetBytes(strPostFields) > ' Set the content length. > WebReq.ContentLength = PostData.Length > Dim tmpStream As Stream > Try > ' Create a request stream. Write the post data to the stream. > tmpStream = WebReq.GetRequestStream() > tmpStream.Write(PostData, 0, PostData.Length) > tmpStream.Close() > Catch ex As Exception > MsgBox("Error occurred while trying OWA authentication!" + vbCrLf + > vbCrLf + ex.Message) > Return Nothing > End Try > ' Get the response from the request. > Dim WebResp As HttpWebResponse = WebReq.GetResponse() > ' Create a stream to capture the response data > Dim tmpStreamRead As New StreamReader(WebResp.GetResponseStream()) > ' Write returned data to a string. > Dim strResponseData As String = tmpStreamRead.ReadToEnd() > tmpStreamRead.Close() > ' Close the response object. > WebResp.Close() > ' Get our returned cookie set. > Return WebResp.Cookies > > End Function > > Private Function ProcessResponse(ByVal xmlnodeResponse As XmlNode, _ > ByVal nsmgr As XmlNamespaceManager, _ > ByRef credCache As CredentialCache, _ > ByRef cookies As CookieCollection) As > Boolean > Dim xmlNodeHref As XmlNode > Dim xmlNodePropStats As XmlNodeList > Dim xmlNodeProp As XmlNode > Dim xmlNodeStatus As XmlNode > Dim xmlNodeMsgClass As XmlNode > Dim strMsgType As String = "" > Dim strEmailName As String = "" > > xmlNodeHref = xmlnodeResponse.SelectSingleNode("a:href", nsmgr) > If xmlNodeHref IsNot Nothing Then > strEmailName = xmlNodeHref.InnerText > End If > If strEmailName.EndsWith("/") Then > Return False > End If > xmlNodePropStats = xmlnodeResponse.SelectNodes("a:propstat", nsmgr) > For Each xmlNodeProp In xmlNodePropStats > xmlNodeStatus = xmlNodeProp.SelectSingleNode("a:status", nsmgr) > If (xmlNodeStatus.InnerText = "HTTP/1.1 200 OK") Then > Debug.Print("Status OK") > xmlNodeMsgClass = > xmlNodeProp.SelectSingleNode("a:prop/d:outlookmessageclass", nsmgr) > Debug.Print(xmlNodeMsgClass.InnerText) > strMsgType = xmlNodeMsgClass.InnerText > End If > Next > If strEmailName <> "" AndAlso strMsgType <> "" Then > GetAttachments(strEmailName, credCache, cookies) > End If > Return True > > End Function > > Private Function GetAttachments(ByVal strEmailName As String, _ > ByRef credCache As CredentialCache, _ > ByRef cookies As CookieCollection) As > Boolean > > '************************* PROCESS ONE EMAIL FOR THE ATTACHMENTS > Dim Request As HttpWebRequest > Dim Response As HttpWebResponse > Dim ResponseXmlDoc As System.Xml.XmlDocument > Dim root As System.Xml.XmlNode > Dim nsmgr As System.Xml.XmlNamespaceManager > Dim InnerPropstatNodes As System.Xml.XmlNodeList > Dim HrefNodes As System.Xml.XmlNodeList > Dim InnerStatusNode As System.Xml.XmlNode > Dim InnerPropNode As System.Xml.XmlNode > > Request = CType(HttpWebRequest.Create(New Uri(strEmailName)), > HttpWebRequest) > Request.CookieContainer = New CookieContainer() > Request.CookieContainer.Add(cookies) > Request.Credentials = credCache > > Request.Method = "X-MS-ENUMATTS" > Response = CType(Request.GetResponse(), System.Net.HttpWebResponse) > Dim responseStream As System.IO.Stream = Response.GetResponseStream() > ResponseXmlDoc = New System.Xml.XmlDocument > ResponseXmlDoc.Load(responseStream) > root = ResponseXmlDoc.DocumentElement > nsmgr = New System.Xml.XmlNamespaceManager(ResponseXmlDoc.NameTable) > > nsmgr.AddNamespace("a", "DAV:") > nsmgr.AddNamespace("d", "http://schemas.microsoft.com/mapi/proptag/") > nsmgr.AddNamespace("e", "urn:schemas:httpmail:") > nsmgr.AddNamespace("n0", "http://schemas.microsoft.com/exchange/") > > ' 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). > InnerPropstatNodes = 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 Then > ' Iterate through the attachment properties. > Dim i As Integer > For i = 0 To HrefNodes.Count - 1 > > ' Use an XPath query to get the DAV:status node from the > DAV:propstat node. > InnerStatusNode = > InnerPropstatNodes(i).SelectSingleNode("a:status", nsmgr) > > ' Check the status of the attachment properties. > If Not InnerStatusNode.InnerText = "HTTP/1.1 200 OK" Then > Debug.Print("Attachment: " & HrefNodes(i).InnerText) > Debug.Print("Status: " & InnerStatusNode.InnerText) > Debug.Print("") > > Else > > ' get the actual full name of the file > InnerPropNode = > InnerPropstatNodes(i).SelectSingleNode("a:prop/e:attachmentfilename", > nsmgr) > If InnerPropNode IsNot Nothing Then > Debug.Print("Attachment filename: " & > InnerPropNode.InnerText) > End If > > Dim reqAttRequest As HttpWebRequest > Dim resAttResponse As HttpWebResponse > reqAttRequest = WebRequest.Create(HrefNodes(i).InnerText) > Try > reqAttRequest.Method = "GET" > reqAttRequest.CookieContainer = New CookieContainer() > reqAttRequest.CookieContainer.Add(cookies) > reqAttRequest.Credentials = credCache > resAttResponse = reqAttRequest.GetResponse() > Dim instream As Stream = > resAttResponse.GetResponseStream() > Dim outStream As New FileStream("C:\" & > InnerPropNode.InnerText, FileMode.Create) > Dim buffer(8192) As Byte > Dim intBytesRead As Integer > > Do > intBytesRead = instream.Read(buffer, 0, > buffer.Length) > If (intBytesRead = 0) Then > Exit Do > End If > outStream.Write(buffer, 0, intBytesRead) > Loop While intBytesRead > 0 > > outStream.Close() > resAttResponse.Close() > > Catch ex As Exception > Debug.Print(ex.Message) > > End Try > > End If > Next > > Else > Debug.Print("No attachments found.") > End If > > ' Clean up. > responseStream.Close() > Response.Close() > > End Function > >
Other interesting topics
Migrate issues Event sink from Exchange 2003 Exchange 2007
Exch2003 - Add a public delegate? Mailbox Movement Code webdav repeating appointments Stand alone MAPI? Exchange 2007, obtaining mailbox list without cmdlets? SMTP Transport event not working for C++ Prevent double booking of resources on Exchange 2007 (direct booking) WEBDAV connect with Exchange2007 Re: MAPI33 - a great blow to exchange development |
|||||||||||||||||||||||