Вы не упомянули, в какой версии .net вы запускаете ее, когда она работает (потому что вы можете настроить таргетинг на сетевой стандарт, но вы не можете запустить на сетевом стандарте). Поэтому я предполагаю, что когда он работает, вы запускаете его на .NET Core, а когда нет, вы работаете на полном .NET 4.6.1, как вы сказали.
Тогда это просто потому, что он был реализован по-разному в .NET Core и полной .NET Framework, как описано в этом выпуске . В этой реализации нет ничего плохого, потому что RFC говорит:
Полезная нагрузка в сообщении запроса GET не имеет определенной семантики;
отправка тела полезной нагрузки по запросу GET может привести к некоторому существующему
реализации, чтобы отклонить запрос.
Таким образом, наличие тела в GET (хотя это почти никогда не является хорошей практикой) само по себе не противоречит этому RFC. Одна реализация (более старая) была разработана, чтобы отклонить ее, но другая (более новая) была разработана, чтобы позволить это, в этом нет ничего более.
Что касается вашего второго вопроса "Какие у меня есть варианты, когда я нацеливаюсь на net461". Я не думаю, что есть простые обходные пути, потому что это поведение HttpWebRequest
, а не HttpClient
. И почти все, что делает веб-запросы, использует HttpWebRequest
внутри.
Хотя есть отвратительные хаки, использующие отражения. Ваш пример может быть изменен следующим образом (работает только при полной загрузке .NET):
static void Main(string[] args) {
// UGLY HACK!
var verbType = typeof(HttpWebRequest).Assembly.GetType("System.Net.KnownHttpVerb");
var getMethodField = verbType.GetField("Get", BindingFlags.Static | BindingFlags.NonPublic);
var getMethod = getMethodField.GetValue(null);
verbType.GetField("ContentBodyNotAllowed", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(getMethod, false);
var jsonPayload = JsonConvert.SerializeObject(new { });
var request = new HttpRequestMessage(HttpMethod.Get, "http://www.stackoverflow.com")
{
Content = new StringContent(jsonPayload, Encoding.UTF8, "application/json")
};
var client = new HttpClient();
var response = client.SendAsync(request).Result;
var responseContent = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(responseContent);
}
Обычно мы используем отражение, чтобы изменить внутреннее поле с именем ContentBodyNotAllowed
из KnownHttpVerb.Get
на false. Используйте на свой страх и риск.