0
votes

Here is my code.

Yes, I am using both, DropNet and Dropbox APIs as I found the DropNet upload works nicely. But I am trying to use the Dropbox one to check for filename (as I couldn't get it to work on DropNet and could not find any help about it online)

I have little doubt that my problem has something to do with the whole Async & Await , as I have never worked with this stuff before.

The File Upload & Get Share both work just fine.

This is a VB.Net Website. When I run it, it freezes in side the DoesDropBoxFileExist function

Imports Dropbox.Api
Imports DropNet
Imports DropNet.Models

Partial Class _Default
  Inherits System.Web.UI.Page
  Dim br As String = "<br>"
  Public FileName As String
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    If FileUpload1.HasFile Then
        Dim dropNet_client As New DropNetClient("", "", "")
        Dim dropBox_client As New DropboxClient("")

        FileName = FileUpload1.PostedFile.FileName
        Response.Write("before: " & FileName & br)
        MsgBox(1)
        FileName = DoesDropBoxFileExist(dropBox_client).Result

        MsgBox(3)
            Response.Write("after: " & FileName & br)

        Dim content As Byte() = FileUpload1.FileBytes


        Dim pathToFile As String = Server.MapPath("~")
        'Response.Write(pathToFile)
        dropNet_client.UploadFile("/AlertImages/", FileName, content, True)

        Dim shareResponse As ShareResponse = dropNet_client.GetShare("/AlertImages/" & FileName)
        Response.Write(shareResponse.Url)

        If Not FileName.ToLower.Contains("pdf") Then
            Dim rawBytes As Byte() = dropNet_client.GetThumbnail("/AlertImages/" & FileName, 2)
            Dim base64String As String = Convert.ToBase64String(rawBytes, 0, rawBytes.Length)
            Image1.ImageUrl = "data:image/png;base64," & base64String
            Image1.Visible = True
        End If

        dropBox_client.Dispose()


    End If
End Sub

Private Async Function DoesDropBoxFileExist(_client As DropboxClient) As Threading.Tasks.Task(Of String)
    Dim rtn As String = FileName

    Dim list = Await _client.Files.ListFolderAsync("/AlertImages")
    MsgBox(2)
    ' show folders then files
    For Each item As Files.Metadata In list.Entries.Where(Function(i) i.IsFolder)
        If item.Name = FileName Then
            FileName = FileName & Now.ToString
        End If
        Response.Write(" < b > " & item.Name & "</b>" & br)
        'Dim list2 As ListFolderResult = Await dbx.Files.ListFolderAsync(item.Name)
        'For Each itm As Files.Metadata In list2.Entries.Where(Function(j) j.IsFile)
        '    Response.Write(item.Name & " : " & item.AsFile.Size & br)
        'Next
    Next

    For Each item As Files.Metadata In list.Entries.Where(Function(i) i.IsFile)
        Response.Write("'" & item.Name & "' '" & FileName & "'" & br)
        If item.Name = FileName Then
            Response.Write("test" & br)
            rtn = FileName & "_" & Now.ToString
        End If
    Next
    Return rtn
    End Function
End Class
1
It would probably be helpful if you clarified where and how it "freezes". E.g., share the output, in order to show where it's stopping. - Greg
By the way, if you just want to check if a specific file exists, you could use GetMetadataAsync with the specific path, instead of listing the whole folder and looking through it. - Greg
It just freezes on "Dim list = Await _client.Files.ListFolderAsync("/AlertImages")" with no output. The browser just keeps thinking. - Yoni

1 Answers

0
votes

METHOD 1

To check in VB.NET if a file exists in Dropbox using the API, you can use this method.

First we create a button with a click event as follows:

    Private Sub btnCheck_Click(sender As Object, e As EventArgs) Handles btnCheck.Click
        'FileToCheck is declared in Form1 as Public Shared
        'FileFound is declared in Form1 as Public Shared
        FileToCheck = cmbFiles.Text
        FileFound = False
        Dim task1 = Task.Run(Function() CheckFileMetadata())
        task1.Wait()
        If FileFound = True Then
            'Do something
        Else
            'Do something else
        End If
    End Sub

And now the function:

    Private Async Function CheckFileMetadata() As Task
        Using dbx = New DropboxClient(DbxToken) 'DbxToken = your token text
            Try
                Await dbx.Files.GetMetadataAsync(Form1.FileToCheck)
                FileFound = True
                Debug.WriteLine("Found it!")
            Catch exapi As ApiException(Of Dropbox.Api.Files.GetMetadataError)
                If exapi.ErrorResponse.IsPath And exapi.ErrorResponse.AsPath.Value.IsNotFound Then
                    Debug.WriteLine("Nothing found at " + Form1.FileToCheck)
                End If
            Catch ex As Exception
                Debug.WriteLine("Error checking file metadata" + vbCrLf + ex.ToString)
            End Try
        End Using
    End Function

This method was adapted from the code here.

METHOD 2

This example demonstrates using VB.NET to recursively iterate through all Dropbox folders to retrieve the names of all files and put them into a collection. Then we check to see if our file is in the collection or not. This method does work, but it's not as efficient as the method above for obvious reasons. I've left it here because it illustrates some additional methods that might help someone.

A couple of notes:

  • If you have a lot of files and/or folders, there can be a delay due to all of the calls that have to be made to do the recursive processing.
  • DbxFolders and DbxFiles are declared as Public in the main form class, like so:
    Public DbxFolders As New List(Of String)
    Public DbxFiles As New List(Of String)
  • Note use of the .tolower since the Dropbox API returns all found paths in all lowers:
    Private Sub btnWalk_Click(sender As Object, e As EventArgs) Handles btnWalk.Click
        DbxFolders.Clear()
        DbxFiles.Clear()
        Dim FindIt As String = "/Folder/File-To-Find.txt".ToLower
        Dim task2 = Task.Run(Function() GetTree(String.Empty))
        task2.Wait()
        If DBFileExists(FindIt) Then MsgBox("Found it!") Else MsgBox("File not found")
    End Sub

    Private Async Function GetTree(dir As String) As Task
        Using dbx = New DropboxClient("Your_Token_Goes_Here")
            Dim list = Await dbx.Files.ListFolderAsync(dir)
            For Each item In list.Entries.Where(Function(i) i.IsFile)
                DbxFiles.Add(item.PathLower)
            Next
            For Each item In list.Entries.Where(Function(i) i.IsFolder)
                DbxFolders.Add(item.PathLower)
                Await GetTree(item.PathLower)
            Next
        End Using
    End Function

    Private Function DBFileExists(file As String) As Boolean
        If DbxFiles.IndexOf(file) > -1 Then Return True Else Return False
    End Function

DISCUSSION

Method 1 is obviously the more efficient of the two methods by far because we only call the API once. Note how the ApiException is used in Try-Catch to determine that the file was not found.

Method 2 illustrates some additional concepts that were helpful to me to learn, so I've left it here because someone may have a scenario where this code and the lists that it creates comes in handy.

Note that when we call GetTree(String.Empty), it would be more efficient to pass the specific folder to look in, instead of starting at the root, since we are attempting to match the full path (/path/to/file.txt) in this example anyway, but I wanted to illustrate the recursive iteration because it might be needed in a different situation.

If you don't care what folder an item is in, but only want to see if it exists in a folder without regard to which folder that is, then you would need to use this recursive iteration but instead of item.pathlower you would want to collect item.name instead.

If desired, you can process the collected file list from Method 2 with a simple loop:

For each DbxFile as string in DbxFiles
    'Do something
Next