Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Will there ever be a CreateFolderAsync() method added to the core Device Portal API? #266

Open
gjrgj opened this issue Aug 17, 2017 · 2 comments

Comments

@gjrgj
Copy link

gjrgj commented Aug 17, 2017

Not being able to generate folders remotely is a small hindrance that I keep running into. It would be really convenient to be able to create my own directory structure on a remote device for file storage. Alternatively, a way of renaming folders remotely would also suffice, as I could have my applications generate the necessary directory structure on the first startup.

@hpsin
Copy link
Contributor

hpsin commented Aug 17, 2017

Hi George - please upvote here: https://wpdev.uservoice.com/forums/110705-universal-windows-platform/suggestions/16509844-folder-upload-creation-and-download
We're investigating the work needed here and which platforms will support it.

@austinbhale
Copy link

If anyone ever runs into this, you can create a new folder name using the following:

public static class DevicePortalExt
{
    /// <summary>
    /// API to retrieve the list of files in a folder.
    /// </summary>
    public static readonly string GetFolderApi = "api/filesystem/apps/folder";

    /// <summary>
    /// Creates a folder inside a Known Folder (e.g. LocalAppData)
    /// </summary>
    /// <param name="knownFolderId">The known folder id for the root of the path.</param>
    /// <param name="folderName">The name of the folder we are creating.</param>
    /// <param name="subPath">An optional subpath to the folder.</param>
    /// <param name="packageFullName">The package full name if using LocalAppData.</param>
    /// <returns>Task tracking completion of the upload request.</returns>
    public static Task CreateFolderAsync(
        this DevicePortal portal,
        string knownFolderId,
        string folderName,
        string? subPath = null,
        string? packageFullName = null)
    {
        Dictionary<string, string> payload = BuildCommonFilePayload(knownFolderId, subPath, packageFullName);
        payload.Add("newfoldername", folderName);
        return portal.PostAsync(GetFolderApi, BuildQueryString(payload));
    }

    /// <summary>
    /// Builds a query string from key value pairs.
    /// </summary>
    /// <param name="payload">The key value pairs containing the query parameters.</param>
    /// <returns>Properly formatted query string.</returns>
    public static string BuildQueryString(Dictionary<string, string> payload)
    {
        string query = string.Empty;

        foreach (KeyValuePair<string, string> pair in payload)
        {
            query += pair.Key + "=" + pair.Value + "&";
        }

        // Trim off the final ampersand.
        query = query.Trim('&');

        return query;
    }

    /// <summary>
    /// Do some common parsing and validation of file explorer parameters.
    /// </summary>
    /// <param name="knownFolderId">The known folder id.</param>
    /// <param name="subPath">The optional subpath for the folder.</param>
    /// <param name="packageFullName">The packagefullname if using LocalAppData.</param>
    /// <returns>Dictionary of param name to value.</returns>
    private static Dictionary<string, string> BuildCommonFilePayload(string knownFolderId, string? subPath, string? packageFullName)
    {
        Dictionary<string, string> payload = [];
        payload.Add("knownfolderid", knownFolderId);

        if (!string.IsNullOrEmpty(subPath))
        {
            if (!subPath.StartsWith("/"))
            {
                subPath = subPath.Insert(0, "/");
            }

            payload.Add("path", subPath);
        }

        if (!string.IsNullOrEmpty(packageFullName))
        {
            payload.Add("packagefullname", packageFullName);
        }
        else if (string.Equals(knownFolderId, "LocalAppData", StringComparison.OrdinalIgnoreCase))
        {
            throw new InvalidOperationException("LocalAppData requires a packageFullName be provided.");
        }

        return payload;
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants