 |
|
 |
Hi,
First I have to tell you, BIG thank you, because you share your knowledge with the rest.
Maybe you could help me, how to list files or directories on the server. I tried with PROPFIND method, but I have no luck. Maybe the method is not right, but which is?
I managed to implement how to move and copy files (code is below of the post), but I stuck with listing.
Oh, not to forget, I vote for you
Regards,
Gregor
************** MOVE ***************************
Private Sub btnMove_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnMove.Click
Dim urlSource As String = "http://www.test1.com/TEST.TXT"
Dim urlDest As String = "http://www.test2.com/TEST.TXT"
Dim userName As String = "username"
Dim password As String = "password"
Try
'Create the request
Dim request As HttpWebRequest = DirectCast(System.Net.HttpWebRequest.Create(urlSource), HttpWebRequest)
'Set the User Name and Password
request.Credentials = New NetworkCredential(userName, password)
'Let the server know we want to "move" a file
request.Method = "MOVE"
' Set the Destination URI.
request.Headers.Add("Destination", urlDest)
' Specify that if a resource already exists at the
' destination URI, it will not be overwritten. The
' server would return a 412 Precondition Failed status code.
request.Headers.Add("Overwrite", "F")
'Get the response from the request
Dim response As HttpWebResponse = DirectCast(request.GetResponse(), HttpWebResponse)
' MsgBox(response.StatusDescription)
MsgBox("Item successfully moved.")
response.Close()
Catch ex As Exception
' Catch any exceptions. Any error codes from the
' MOVE method requests on the server will be caught
' here, also.
Console.WriteLine(ex.Message)
End Try
End Sub
***************** COPY **********************
Private Sub btnCopy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCopy.Click
Dim urlSource As String = "http://www.test1.com/TEST.TXT"
Dim urlDest As String = "http://www.test2.com/TEST.TXT"
Dim userName As String = "username"
Dim password As String = "password"
'Create the request
Dim request As HttpWebRequest = DirectCast(System.Net.HttpWebRequest.Create(urlSource), HttpWebRequest)
'Set the User Name and Password
request.Credentials = New NetworkCredential(userName, password)
'Let the server know we want to "copy" a file
request.Method = "COPY"
' Set the Destination URI.
request.Headers.Add("Destination", urlDest)
' Specify that if a resource already exists at the
' destination URI, it will not be overwritten. The
' server would return a 412 Precondition Failed status code.
request.Headers.Add("Overwrite", "F")
'Get the response from the request
Dim response As HttpWebResponse = DirectCast(request.GetResponse(), HttpWebResponse)
MsgBox(response.StatusDescription)
response.Close()
End Sub
|
|
|
|
 |
|
 |
Here's how I did it:
Public Overrides Function GetDirectoryListing() As DirectoryItemsTable
'Create the request
Dim request As HttpWebRequest = Nothing
Dim response As WebResponse = Nothing
Dim reader As IO.StreamReader = Nothing
Dim log As New RftErrorLogging.Log()
Try
request = CreateRequest(mConnectionInfo.UrlAndPort, _
WebRequestMethods.Http.Get, False)
Catch ex As Exception
Dim msg As String = "An error has occurred attempting to Create the Request " & _
"in Http.GetDirectoryListing()"
Dim x As New Exception(msg, ex)
log.LogException(x)
End Try
Try
response = request.GetResponse()
Catch ex As Exception
Dim msg As String = "An error has occurred attempting to Get the Response " & _
"in Http.GetDirectoryListing()"
Dim x As New Exception(msg, ex)
log.LogException(x)
End Try
Try
reader = New IO.StreamReader(response.GetResponseStream())
Catch ex As Exception
Dim msg As String = "An error has occurred attempting to Get the Response " & _
"Stream in Http.GetDirectoryListing()"
Dim x As New Exception(msg, ex)
log.LogException(x)
End Try
Dim html As String = reader.ReadToEnd()
reader.Close()
reader.Dispose()
reader = Nothing
response.Close()
response = Nothing
'Get the list and return it.
Dim table As DirectoryItemsTable = Nothing
Try
table = ParseDirectory(html)
table.AcceptChanges()
Catch ex As Exception
Dim msg As String = "An error has occurred attempting to Parse the Directory " & _
"in Http.GetDirectoryListing()"
Dim x As New Exception(msg, ex)
log.LogException(x)
End Try
Return table
End Function
|
|
|
|
 |
|
 |
Hi,
Thanks, I will try it tomorrow, but I know that will work
You really rock.
Gregor
|
|
|
|
 |
|
 |
I hope so! It worked for me on my server.
That example does not show you how to parse the directory from the html that is retrieved, but it does show you how to retrieve it.
|
|
|
|
 |
|
 |
Problem was, how to get list of directories from server, so your example is just what I need. And because all your examples work for me, I belive, this one will be fine for me.
Thanks again.
|
|
|
|
 |
|
 |
Not to revive an old topic, but I just had to work this out for a project.
I ended up using the "PROPFIND" command and XML parsing to work my way through a server. This is the function used to do the actual webDAV communication. Extracting directory and file names from the XML is handled separately.
Private Function getPropsXML(ByVal relativeURL As String) As Xml.XmlTextReader
Dim req As HttpWebRequest
Dim response As HttpWebResponse
Dim srRdr As System.IO.StreamReader
Dim outBytes() As Byte
Try
req = HttpWebRequest.Create(_STG_WBDAV_URL_ & relativeURL)
'The server used basic authentication, so we need to add the appropriate header
req.Headers.Add("Authorization: Basic " & encryptBSCPassword(_BSC_UNAME_, _BSC_PWRD_))
'Tells the server how many layers of properties to return. 1 returns just the current page
'and it's immediate children
req.Headers.Add("Depth: 1")
req.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
req.Method = "PROPFIND"
req.ContentType = "text/xml"
'this XML string tells the webdav server to return all properties. There's an excellent explanation here - >http://www.webdav.org/specs/rfc2518.html#ELEMENT_depth[^]
Dim xmlBodStr As String = " "
Dim queryByte() As Byte = System.Text.Encoding.ASCII.GetBytes(xmlBodStr)
req.ContentLength = queryByte.Length
Dim queryStream As System.IO.Stream = req.GetRequestStream
queryStream.Write(queryByte, 0, queryByte.Length)
queryStream.Close()
response = req.GetResponse
srRdr = New System.IO.StreamReader(response.GetResponseStream())
Dim swXML As New System.IO.FileStream("C:\temp\propFind.xml", IO.FileMode.OpenOrCreate)
Dim outStr As String = srRdr.ReadToEnd
outBytes = System.Text.Encoding.UTF8.GetBytes(outStr)
swXML.Write(outBytes, 0, outBytes.Length)
swXML.Flush()
swXML.Close()
srRdr.Close()
response.Close()
'MsgBox(outStr)
Catch ex As Exception
MsgBox(ex.Message & " : WebDAV Communication Error")
Return Nothing
End Try
Dim pbmList As New List(Of String)
Try
Dim ms As New IO.MemoryStream(outBytes)
Dim xmlRdr As New System.Xml.XmlTextReader(ms)
Return xmlRdr
Catch ex As Exception
MsgBox("XML Creation Error: " & ex.Message)
Return Nothing
End Try
End Function
|
|
|
|
 |
|
 |
Hi,
I made this small WebDAV client for C# that also adds a bit more functionality for operating on a WebDAV share. Feel free to incorporate that into your VB.NET examples.
I was wondering on what WebDAV server you used the SendChunks and the translate header tricks on.
Also, do you use any public WebDAV server(s) for testing your code?
Best regards,
Kees
|
|
|
|
 |
|
 |
Hi Kees, Thank you for taking the time to read my article and post a comment!
Also, thank you for the C# client as well.
Concerning what WebDAV server I used SendChunks and the translate header tricks on: I'm not completely sure. My company had an internal FTP site that used to transmit data to and from our customers. Because of new SAS 70 requirements, we outsourced it to an external IT company that set up our WebDAV server... So I don't know how they set it up, or configured it. I do know that regular FTP software would not work with it. The IT company had us setup Windows WebDAV folders to access the site. When I wrote my program, I did extensive research about interacting with WebDAV folders, and once I got it nailed down it worked like a charm!
Thanks again!
|
|
|
|
 |
|
 |
Hi there
More testing... If you remove code which handles the progressbar - an exception Protocol Error fires?
If I insert a little pause
for i=1 to 10000
application.doevents()
next
the exception is not fired ???
Anyone have an idea what the problem is?
I tried something like
' System.GC.WaitForPendingFinalizers()
' System.GC.WaitForFullGCApproach()
' System.GC.WaitForFullGCComplete()
System.GC.Collect()
no result
|
|
|
|
 |
|
 |
Ups
I've just tried this a small change in the Do-Loop
And after several tests - the exceptions is no longer an issue...
Do
bytesRead = fs.Read(bytes, 0, bytes.Length)
If bytesRead > 0 Then
totalBytesRead += bytesRead
s.Write(bytes, 0, bytesRead)
End If
System.GC.Collect()
Application.DoEvents()
Loop While bytesRead > 0
|
|
|
|
 |
|
 |
Hi Michael,
Sorry, but I haven't experienced that kind of behavior. It works perfect for me whether I have a progress bar or a tight loop.
I honestly don't know about using garbage collection there... Do you have a pretty good understanding of garbage collection? (maybe I don't) - Within the Do...Loop, you're not allocating new memory, so the garbage collection doesn't have anything new to remove from either the stack or heap (unless its from something else earlier). The bytesRead array is declared 1 time, and is reused throughout the whole loop. At the end of the method the pointers to the array are destroyed, and the garbage collection will remove the array from the heap at some point in the future. As a general rule - allocate an object and forget about it. The garbage collector will destroy it when it's no longer needed.
Maybe you can try sleeping the thread instead and see if that helps:
Threading.Thread.Sleep(250) '1000 = 1 second
|
|
|
|
 |
|
 |
Hi
Well it was just a trial - I'm not in deept of the GC.
I'll try with the sleep.... but then again - how long should the sleep be!
It seems that the stream is not ready - filled when the request is fired - so there seems to be a short delay.
I also tried with a for-next loop after the do-loop that seemed to helped.
I agree that the GC should not have any effect on the program...
I'll post back if I find some news about it.
Best regards
Michael
|
|
|
|
 |
|
|
 |
|
 |
I also had a similar problem when using only the loop. I put a sleep in and it worked. I don't like this work around. Do you have any more info on this?
Thanks.
|
|
|
|
 |
|
 |
Actually, I use a progressbar, and sleep it as well, so unfortunately I don't have any more info. Sorry. :(
|
|
|
|
 |
|
 |
Can one make a "dir" on the webdav server?
Can one delete a file on the webdav server?
Thanks in advance
Michael
|
|
|
|
 |
|
 |
Hi Michael,
I haven't tried to make a directory yet, so I'm not sure about that one, but it is in my plans, so as soon as I figure it out I'll let you know. However, I did find that I could use the Delete method to Delete a file. Here's a complete example:
Dim url As String = "url to the file you want to delete"
Dim userName As String = "UserName"
Dim password As String = "Password"
'Create the request
Dim request As HttpWebRequest = DirectCast(System.Net.HttpWebRequest.Create(url), HttpWebRequest)
'Set the User Name and Password
request.Credentials = New NetworkCredential(userName, password)
'Let the server know we want to "delete" a file
request.Method = "DELETE"
'Get the response from the request
Dim response As HttpWebResponse = DirectCast(request.GetResponse(), HttpWebResponse)
MsgBox(response.StatusDescription)
response.Close()
Let me know if you have any questions about that.
By the way, if you found this article helpful, would you mind voting for it?
Go to: http://www.codeproject.com/[^]
Look for the "Latest Surveys - Please Vote!" at the top.
Click "Best VB.NET article of May 2009.
Select "How to Download a File from a WebDAV Server in VB.NET"
Thanks!
VBRocks
|
|
|
|
 |
|
 |
Hey there
It worked just perfect.
I've encapsulated the parts in a simple class - so now I'm ready to create an file sync tool for our internet - exciting for us.
Best regards
Michael
|
|
|
|
 |
|
 |
That's cool! That's what I did too. Our project started out being a simple program that monitors the WebDAV site for new files, and then downloads them; but then it morphed into a full-blown File Transfer program. I have an HTTP class that handles HTTP and HTTPS requests, plus I have an FTP class that handles FTP and FTPES requests.
Good luck with it!
|
|
|
|
 |
|
 |
Hi,
Did you manage "dir" on the webdav server? Could you please, tell me how you did it?
Regards,
Gregor
|
|
|
|
 |
|
 |
Here's how I got the directory listing on my server:
Public Overrides Function GetDirectoryListing() As DirectoryItemsTable
'Create the request
Dim request As HttpWebRequest = Nothing
Dim response As WebResponse = Nothing
Dim reader As IO.StreamReader = Nothing
Dim log As New RftErrorLogging.Log()
Try
request = CreateRequest(mConnectionInfo.UrlAndPort, _
WebRequestMethods.Http.Get, False)
Catch ex As Exception
Dim msg As String = "An error has occurred attempting to Create the Request " & _
"in Http.GetDirectoryListing()"
Dim x As New Exception(msg, ex)
log.LogException(x)
End Try
Try
response = request.GetResponse()
Catch ex As Exception
Dim msg As String = "An error has occurred attempting to Get the Response " & _
"in Http.GetDirectoryListing()"
Dim x As New Exception(msg, ex)
log.LogException(x)
End Try
Try
reader = New IO.StreamReader(response.GetResponseStream())
Catch ex As Exception
Dim msg As String = "An error has occurred attempting to Get the Response " & _
"Stream in Http.GetDirectoryListing()"
Dim x As New Exception(msg, ex)
log.LogException(x)
End Try
Dim html As String = reader.ReadToEnd()
reader.Close()
reader.Dispose()
reader = Nothing
response.Close()
response = Nothing
'Get the list and return it.
Dim table As DirectoryItemsTable = Nothing
Try
table = ParseDirectory(html) 'Parse the directory from the returned html
table.AcceptChanges()
Catch ex As Exception
Dim msg As String = "An error has occurred attempting to Parse the Directory " & _
"in Http.GetDirectoryListing()"
Dim x As New Exception(msg, ex)
log.LogException(x)
End Try
Return table
End Function
|
|
|
|
 |
|
 |
I've just tried the code against an Apache server, using HTTPS. I've combined the to programsnifs and they work just fine.
Thanks for the effort.
How can one delete a file on the WebDav server?
Regards
Michael
|
|
|
|
 |
|
 |
Thanks for second article
|
|
|
|
 |
|
 |
You're welcome!
By the way, if you found these articles helpful, would you mind voting for them?
Go to: <a href="http://www.codeproject.com/">http://www.codeproject.com/</a>[<a href="http://www.codeproject.com/" target="_blank" title="New Window">^</a>]
Look for the "Latest Surveys - Please Vote!" at the top.
Click "Best VB.NET article of May 2009.
Select "How to Download a File from a WebDAV Server in VB.NET"
Thanks!
VBRocks
|
|
|
|
 |
|
 |
Great article!
I recently had to integrate a .net application with exchange which can be done using WebDAV. I too found it very difficult to find any good concrete examples.
For anyone who is interested though, I have written a series of posts on what I did:
Part 1
Part 2
Part 3
Part 4
Part 5
|
|
|
|
 |