How to add content header to Flurl

2019-08-30 23:49发布

问题:

I would like to know how to add a content header to a flurl-statement. The onedrive implementation requires me to add a content-type header to the content, and tried every possible solution with no luck.

I'm forced to use the regular httpclient with the following code.

Public Async Function UploadFile(folder As String, filepath As String) As Task(Of Boolean) Implements ICloud.UploadFile
        Dim data As Byte() = File.ReadAllBytes(filepath)
        Dim uploadurl As String = "drive/items/" + folder + ":/" + Path.GetFileName(filepath) + ":/" + "content?access_token=" + Token.access_token


        Using client As New HttpClient()
            client.BaseAddress = New Uri(ApiUrl)

            Dim request As HttpRequestMessage = New HttpRequestMessage(HttpMethod.Put, uploadurl)

            request.Content = New ByteArrayContent(data)
            request.Content.Headers.Add("Content-Type", "application/octet-stream")
            request.Content.Headers.Add("Content-Length", data.Length)

            Dim response = Await client.SendAsync(request)

            Return response.IsSuccessStatusCode
        End Using
    End Function

I already tried the regular PutJsonAsync method of Flurl, but with no luck. It's the only non-flurl piece remaining in my code.

Thanx in advance.

回答1:

The real issue here is that there's currently no out-of-the-box support for sending streams or byte arrays in Flurl. I plan to add some soon, but with the implementation details you already have it's easy to add this yourself with an extension method. (Forgive the C#, hopefully you can translate to VB.)

public static Task<HttpResponseMessage> PutFileAsync(this FlurlClient client, string filepath) 
{
    var data = File.ReadAllBytes(filepath);
    var content = new ByteArrayContent(data);
    content.Headers.Add("Content-Type", "application/octet-stream");
    content.Headers.Add("Content-Length", data.Length);
    return client.SendAsync(HttpMethod.Put, content: content);
}

The above works if you already have a FlurlClient, but as the docs describe it's a good idea to have corresponding string and Url extensions, which can just delegate to the above method:

public static Task<HttpResponseMessage> PutFileAsync(this Url url, string filepath)
{
    return new FlurlClient(url).PutFileAsync(filepath);
}

public static Task<HttpResponseMessage> PutFileAsync(this string url, string filepath)
{
    return new FlurlClient(url).PutFileAsync(filepath);
}

Tuck those away in a static helper class and they should work seamlessly with Flurl:

await uploadurl.PutFileAsync(filepath)