How to enable content with a GET request?

EDIT: Please note: I know that the essence of the problem lies in the service with which I need to communicate, does not comply with the protocol. This is software that I cannot touch and will not be changed in the near future. Thus, I need help in circumventing the problem and protocol violation. Development at its best!

I am trying to communicate with an external service. Someone decided to separate the various calls not only into different folders, but also into types of HTTP requests. The problem here is that I need to send a GET request containing the content.

Yes, this violates the protocol. Yes, it works if I formulate a call using Linux commands. Yes, this works if I manually create a call in Fiddler (although Fiddler is angry at breaking the protocol)

When I make my call, it ends with the async method. However, when sending it, an error occurs:

An exception was thrown: "System.Net.ProtocolViolationException" in mscorlib.dll ("Cannot send content body using this type of verb.")

Code to call:

    /// <summary>
    /// Gets a reading from a sensor
    /// </summary>
    /// <param name="query">Data query to set data with</param>
    /// <returns></returns>
    public async Task<string> GetData(string query)
    {
        var result = string.Empty;

        try
        {
            // Send a GET request with a content containing the query. Don't ask, just accept it 
            var msg = new HttpRequestMessage(HttpMethod.Get, _dataApiUrl) { Content = new StringContent(query) };
            var response = await _httpClient.SendAsync(msg).ConfigureAwait(false);

            // Throws exception if baby broke
            response.EnsureSuccessStatusCode();

            // Convert to something slightly less useless
            result = await response.Content.ReadAsStringAsync();
        }
        catch (Exception exc)
        {
            // Something broke ¯\_(ツ)_/¯
            _logger.ErrorException("Something broke in GetData(). Probably a borked connection.", exc);
        }
        return result;
    }

_httpClient is created in the constructor and is System.Net.Http.HttpClient.

Does anyone have an idea to override the usual protocols for HttpClient and make it make the call as a GET call, but with the contents containing my request for the server?

+4
source share
1 answer

For me, a less destructive way to achieve this is to set the field ContentBodyNotAllowed Get KnownHttpVerbto falseusing reflection. You may try:

public async Task<string> GetData(string query)
{
    var result = string.Empty;
    try
    {
        var KnownHttpVerbType = typeof(System.Net.AuthenticationManager).Assembly.GetTypes().Where(t => t.Name == "KnownHttpVerb").First();
        var getVerb = KnownHttpVerbType.GetField("Get", BindingFlags.NonPublic | BindingFlags.Static);
        var ContentBodyNotAllowedField = KnownHttpVerbType.GetField("ContentBodyNotAllowed", BindingFlags.NonPublic | BindingFlags.Instance);
        ContentBodyNotAllowedField.SetValue(getVerb.GetValue(null), false);

        var msg = new HttpRequestMessage(HttpMethod.Get, _dataApiUrl) { Content = new StringContent(query) };
        var response = await _httpClient.SendAsync(msg).ConfigureAwait(false);
        response.EnsureSuccessStatusCode();

        result = await response.Content.ReadAsStringAsync();
    }
    catch (Exception exc)
    {
        _logger.ErrorException("Something broke in GetData(). Probably a borked connection.", exc);
    }
    return result;
}
+1

Source: https://habr.com/ru/post/1609599/


All Articles