Search code examples
c#uwpwindows-10-universalpushbullet

Upload file to Pushbullet in Windows 10 app c#


I'm currently using Pushbullet API and need to upload a file.

I can successfully get an upload url as specified in the docs using this method:

public static async Task<Uploads> GetUploadUrl(string file_name, string file_type)
    {
        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Add("Access-Token", AccessToken);

            var json = new JObject
            {
                ["file_name"] = file_name,
                ["file_type"] = file_type
            };

            var result = await client.PostAsync(new Uri(_uploadUrl, UriKind.RelativeOrAbsolute), new HttpStringContent(json.ToString(), UnicodeEncoding.Utf8, "application/json"));
            if (result.IsSuccessStatusCode)
            {
                var textresult = await result.Content.ReadAsStringAsync();
                return JsonConvert.DeserializeObject<Uploads>(textresult);
            }
        }

        return null;
    }

The problem is when I try to upload the file. I'm currently using this method:

 public static async Task<bool> UploadFile(StorageFile file, string upload_url)
    {
        try
        {
            System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
            var content = new MultipartFormDataContent();
            if (file != null)
            {
                var streamData = await file.OpenReadAsync();
                var bytes = new byte[streamData.Size];
                using (var dataReader = new DataReader(streamData))
                {
                    await dataReader.LoadAsync((uint)streamData.Size);
                    dataReader.ReadBytes(bytes);
                }
                var streamContent = new ByteArrayContent(bytes);
                content.Add(streamContent);
            }
            client.DefaultRequestHeaders.Add("Access-Token", AccessToken);
            var response = await client.PostAsync(new Uri(upload_url, UriKind.Absolute), content);
            if (response.IsSuccessStatusCode)
                return true;
        }
        catch { return false; }

        return false;
    }

but I get a Http 400 error. What's the right way to upload a file using multipart/form-data in a UWP app?


Solution

  • HTTP 400 error indicates Bad Request, it means the request could not be understood by the server due to malformed syntax. In the other word, the request sent by the client doesn't follow server's rules.

    Let's look at the document, and we can find in the example request it uses following parameter:

    -F [email protected]

    So in the request, we need to set the name for the uploaded file and the name should be "file". Besides, in this request, there is no need to use access token. So you can change your code like following:

    public static async Task<bool> UploadFile(StorageFile file, string upload_url)
    {
        try
        {
            System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
            var content = new MultipartFormDataContent();
            if (file != null)
            {
                var streamData = await file.OpenReadAsync();
                var bytes = new byte[streamData.Size];
                using (var dataReader = new DataReader(streamData))
                {
                    await dataReader.LoadAsync((uint)streamData.Size);
                    dataReader.ReadBytes(bytes);
                }
                var streamContent = new ByteArrayContent(bytes);
                content.Add(streamContent, "file");
            }
            //client.DefaultRequestHeaders.Add("Access-Token", AccessToken);
            var response = await client.PostAsync(new Uri(upload_url, UriKind.Absolute), content);
            if (response.IsSuccessStatusCode)
                return true;
        }
        catch { return false; }
    
        return false;
    }
    

    Then your code should be able to work. You will get a 204 No Content response and UploadFile method will return true.