tmenier / Flurl

Fluent URL builder and testable HTTP client for .NET
https://flurl.dev
MIT License
4.23k stars 387 forks source link

[feature request] support GetJsonAsync with body #836

Closed emako closed 3 months ago

emako commented 3 months ago

Although it is not good to use GET method with body, but it is technically allowed by http protocol.

And actually I need to use it.

 public static async Task<T> GetJsonAsync<T>(this IFlurlRequest request, object body, HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead, CancellationToken cancellationToken = default);
emako commented 3 months ago

My temporary solution

    public static async Task<T> GetJsonAsync<T>(this IFlurlRequest request, object body, CancellationToken cancellationToken = default)
    {
        // Not support cancellation.
        _ = cancellationToken;

        HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(request.Url);
        webRequest.ContentType = "application/json";
        webRequest.Method = "GET";
        webRequest.PreAuthenticate = true;
        webRequest.Headers.Add("Authorization", "Bearer " + AccessToken);

        object currentMethod = typeof(HttpWebRequest)
            .GetProperty("CurrentMethod", BindingFlags.NonPublic | BindingFlags.Instance)
            .GetValue(webRequest);

        currentMethod.GetType()
            .GetField("ContentBodyNotAllowed", BindingFlags.NonPublic | BindingFlags.Instance)
            .SetValue(currentMethod, false);

        using StreamWriter streamWriter = new(webRequest.GetRequestStream());
        await streamWriter.WriteAsync(JsonSerializer.Serialize(body));
        streamWriter.Close();

        HttpWebResponse response = (HttpWebResponse)await webRequest.GetResponseAsync();
        using Stream responseStream = response.GetResponseStream();
        using StreamReader myStreamReader = new(responseStream, Encoding.UTF8);
        string json = await myStreamReader.ReadToEndAsync();

        return JsonSerializer.Deserialize<T>(json)!;
    }
emako commented 3 months ago

This support is not suitable

tmenier commented 3 months ago

It's actually far easier than that - use SendJsonAsync: https://flurl.dev/docs/fluent-http/#additional-use-cases