如何在GET请求中包含内容?

4

编辑:请注意,我知道问题的核心在于我需要与之通信的服务没有遵循协议。这是我无法接触并且不会很快更改的软件。因此,我需要帮助规避问题并突破协议。开发工作正是如此!

我正在尝试与外部服务通信。制造它的人决定将各种调用分成不同的文件夹和HTTP请求类型。问题在于,我需要发送一个包含内容的GET请求。

是的,这违反了协议。 是的,如果我使用Linux命令进行调用,它将起作用。 是的,如果我在Fiddler中手动制作呼叫,它可以起作用(虽然Fiddler对协议的违反感到愤怒)

当我制作我的呼叫时,它被包装在异步方法中。然而,发送它会导致错误:

“mscorlib.dll”中引发异常:“System.Net.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调用,但内容包含我的服务器查询吗?


你不能将查询添加到获取URL中吗? - Steven
目前,唯一的选项是通过内容部分发送GET请求并查询。我认为,在与不是每个人都同意且一半的东西只是被黑客攻击的大学合作中,这将使得我的博士学位非常痛苦。 - Tank
2
@Tank,HTTP明文传输只是一堆字节的发送和接收。如果不使用HttpClient的任何花式功能,则可以使用流读取器和写入器通过TCP连接发送请求并接收响应(这将完全不知道它违反了HTTP规则;))。 - Kuba Wyrostek
1
我查看了 HttpClient 使用的代码,对我来说似乎很难避免它的检查,除非大量重写代码。你可以考虑使用 WebRequest 吗? - Matteo Umili
@Tank,我正在检查“HttpWebRequest”,即使在这里也很难避免动词检查。 - Matteo Umili
显示剩余5条评论
1个回答

1
对我来说,实现这一点的较少破坏性方法是使用反射将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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接