如何在GET请求中包含内容

本文关键字:包含内 请求 GET | 更新日期: 2023-09-27 18:15:09

EDIT: 请注意,我知道问题的核心在于我需要与之通信的服务没有遵循协议。这是一个软件,我不能触摸,不会很快改变。因此,我需要帮助规避问题和打破协议。最好的发展!

我正在尝试与外部服务通信。制作它的人不仅决定将各种调用拆分到不同的文件夹中,还决定将HTTP请求类型拆分到不同的文件夹中。这里的问题是,我需要发送一个包含内容的GET请求。

是的,这违反了协议。是的,如果我使用Linux命令制定调用,这就可以工作。是的,如果我在Fiddler中手动编写调用,这是有效的(尽管Fiddler对违反协议感到愤怒)

当我编写调用时,它被封装在一个异步方法中。然而,发送它会导致错误:

抛出异常:'System.Net. net . 'mscorlib.dll中的ProtocolViolationException'("不能发送带有此动词类型的内容体。")

调用代码:

    /// <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是在构造函数中创建的,是一个System.Net.Http.HttpClient。

有没有人知道如何重写HttpClient的常规协议,并强制它作为GET调用进行调用,但内容包含我对服务器的查询?

如何在GET请求中包含内容

对我来说,实现这一目标的破坏性较小的方法是使用反射将Get KnownHttpVerbContentBodyNotAllowed字段设置为false。你可以试试这个:

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;
}