Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change the HTTP Request Content Type for FLURL Client?

I am using flurl to submit HTTP request and this is very useful. Now I need to change the "Content-Type" header for some of the requests to "application/json;odata=verbose"

    public async Task<Job> AddJob()
    {

        var flurlClient = GetBaseUrlForGetOperations("Jobs").WithHeader("Content-Type", "application/json;odata=verbose");
        return await flurlClient.PostJsonAsync(new
        {
            //Some parameters here which are not the problem since tested with Postman

        }).ReceiveJson<Job>();
    }

    private IFlurlClient GetBaseUrlForOperations(string resource)
    {
        var url = _azureApiUrl
            .AppendPathSegment("api")
            .AppendPathSegment(resource)
            .WithOAuthBearerToken(AzureAuthentication.AccessToken)
            .WithHeader("x-ms-version", "2.11")
            .WithHeader("Accept", "application/json");
        return url;
    }

You can see how I tried to add the header above (.WithHeader("Content-Type", "application/json;odata=verbose"))

Unfortunately this gives me following error:

"InvalidOperationException: Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects."

I also tried flurl's "ConfigureHttpClient" method but could not find how/where to set the content type header.

like image 999
mJay Avatar asked Jun 13 '17 07:06

mJay


People also ask

What is the definition of Flurl?

So, What is Flurl? Flurl stands for the Fluent URL. Quoting Flurl's home page: Flurl is a modern, fluent, asynchronous, testable, portable, buzzword-laden URL builder and HTTP client library for . NET. It's simple as that.

What is FlurlClient?

FlurlClient is a lightweight wrapper around HttpClient and is tightly bound to its lifetime. It implements IDisposable , and when disposed will also dispose HttpClient . FlurlClient includes a BaseUrl property, as well as Headers , Settings , and many of the fluent methods you may already be familiar with.


2 Answers

This answer is outdated. Upgrade to latest version (2.0 or above) and the problem goes away.

It turns out the real issue has to do with how the System.Net.Http APIs validate headers. It makes a distinction between request-level headers and content-level headers, which I've always found a bit odd since raw HTTP makes no such distinction (except perhaps in multipart scenarios). Flurl's WithHeader adds headers to the HttpRequestMessage object but is failing validation for Content-Type, which it expects to be added to the HttpContent object.

Those APIs do allow you to skip validation, and although Flurl doesn't expose it directly, you can get under the hood pretty easily, without breaking the fluent chain:

return await GetBaseUrlForGetOperations("Jobs")
    .ConfigureHttpClient(c => c.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json;odata=verbose"))
    .PostJsonAsync(new { ... })
    .ReceiveJson<Job>();

This is probably the best way to do what you need and still take advantage of Flurl's goodness, i.e. not have to directly deal with serialization, HttpContent objects, etc.

I'm strongly considering changing Flurl's AddHeader(s) implementations to use TryAddWithoutValidation based on this issue.

like image 199
Todd Menier Avatar answered Sep 18 '22 02:09

Todd Menier


The comments and another post I found (will add reference when I find it again) have pointed me to the right direction. The solution for my problem looks like:

        var jobInJson = JsonConvert.SerializeObject(job);
        var json = new StringContent(jobInJson, Encoding.UTF8);
        json.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json; odata=verbose");

        var flurClient = GetBaseUrlForOperations("Jobs");

        return await flurClient.PostAsync(json).ReceiveJson<Job>();

Edit: Found the related SO question: Azure encoding job via REST Fails

like image 42
mJay Avatar answered Sep 18 '22 02:09

mJay