I have visual studio 2022 and am using dot net maui building on the base example by James Montemagno. I am calling the dropbox api (visual studio package) to download a file and it works fine on windows, but when I switch to the android emulator I get this Error:
Error in call to API function "files/download":Bad HTTP "Content-Type" header: "application/x-www-form-urlencoded". Expecting one of "text/plain; charset=utf-8","application/octet-stream","application/octest-stream;charset=utf-8"
My code is very straightforward and listed below. I have googled this error and there were previous fixes but none seem to apply to the latest version of Visual Studio - hence the CreateClient()
using Dropbox.Api.Files;
using Dropbox.Api.Users;
public HttpClient CreateClient()
{
#if __ANDROID__
return new HttpClient(new Xamarin.Android.Net.AndroidMessageHandler());
#else
return new HttpClient();
#endif
}
public async Task GetInfoFromDropbox()
{
string szFileName = "Somefile.dat";
string szDropBoxToken = "myDropboxToken";
httpClient = CreateClient();
var objDbx = new DropboxClient(szDropBoxToken, new DropboxClientConfig() { HttpClient = httpClient });
// Code fails here
var result = await objDbx.Files.DownloadAsync(szFileName);
// carries on working if windows
var result2 = await result.GetContentAsStreamAsync();
}
I found the answer and it was a little more complicated than the supplied answer by user 21374054:
I needed the conditional #if ANDROID as compiling for other platforms failed - otherwise the code is similar, BUT there was also a thread error which I resolved in the ReadDropbox routine
so here is the code:
#if __ANDROID__
public class MyAndroidMessageHandler : Xamarin.Android.Net.AndroidMessageHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request.RequestUri.AbsolutePath.Contains("files/download"))
{
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
}
return base.SendAsync(request, cancellationToken);
}
}
#endif
public HttpClient CreateClient()
{
#if __ANDROID__
return new HttpClient(new MyAndroidMessageHandler());
#else
return new HttpClient();
#endif
}
public async Task<DataTable> ReadDropboxFile(string szFileName)
{
DataSet dataset = new DataSet();
DataTable datatable = new DataTable();
string szDropBoxToken = m_szDropBoxToken;
httpClient = CreateClient();
var objDbx = new DropboxClient(szDropBoxToken, new DropboxClientConfig() { HttpClient = httpClient });
// this trick uses another thread to avoid an android error of using the main thread
await Task.Run(async () => {
var result = await objDbx.Files.DownloadAsync(szFileName);
var result2 = await result.GetContentAsStreamAsync();
dataset.ReadXml(result2);
});
datatable = dataset.Tables[0];
return datatable;
}