У меня был код ниже для вызова метода POST с телом json, но я получаю The remote server returned an error: (400) Bad Request., когда он выполняет код using (var response = (HttpWebResponse)request.GetResponse()).
Мой код работал нормально только в том случае, если необработанные данные не требуются.
Пример json
{"redirect":"www.google.com","subscriptionTypeId":76670001,"marketingCampaign":{"conversionId":12345,"agency":"","medium":"","name":"","source":""}}
Мой код
public static bool HTTPRequest(string URL, RequestMethod CallMethod, Hashtable RequestHeaders, string json, ref StringBuilder httpRequestHeader, ref string jsonResponse, bool preparepurchaseFlag)
{
try
{
var request = (HttpWebRequest)WebRequest.Create(URL);
request.Method = CallMethod.ToString();
request.ContentLength = 0;
//Header
if (RequestHeaders != null)
{
foreach (string ParamKey in RequestHeaders.Keys)
{
if (ParamKey == "Content-Type")
{
request.ContentType = RequestHeaders[ParamKey].ToString();
}
else if (ParamKey.ToLower() == "accept")
{
request.Accept = RequestHeaders[ParamKey].ToString();
}
else
{
request.Headers[ParamKey] = RequestHeaders[ParamKey].ToString();
}
}
}
//Body
if (!string.IsNullOrEmpty(json))
{
var encoding = new UTF8Encoding();
var bytes = Encoding.GetEncoding("UTF-8").GetBytes(json);
request.ContentLength = bytes.Length;
using (var writeStream = request.GetRequestStream())
{
writeStream.Write(bytes, 0, bytes.Length);
}
}
//Log Request Header
httpRequestHeader.AppendLine("curl --location --request " + request.Method.ToString());
httpRequestHeader.AppendLine(request.RequestUri.ToString());
foreach (string ParamKey in RequestHeaders.Keys)
{
httpRequestHeader.Append("--header ");
httpRequestHeader.AppendLine(ParamKey + ": " + RequestHeaders[ParamKey].ToString());
}
if (preparepurchaseFlag)
{
httpRequestHeader.Append("--data-raw ");
httpRequestHeader.AppendLine(json);
}
using (var response = (HttpWebResponse)request.GetResponse())
{
var responseValue = string.Empty;
if (response.StatusCode != HttpStatusCode.OK)
{
var message = String.Format("Request failed. Received HTTP {0}", response.StatusCode);
throw new Exception(message);
}
var httpWebResponse = (HttpWebResponse)request.GetResponse();
using (var responseStream = httpWebResponse.GetResponseStream())
{
if (responseStream != null)
using (var reader = new StreamReader(responseStream))
{
responseValue = reader.ReadToEnd();
}
}
jsonResponse = responseValue;
return true;
}
}
catch (WebException e)
{
//catch
return false;
}
catch (Exception ex)
{
//catch
}
}
@ProgrammingLlama хммм, я думаю, вы указываете на очень ценный комментарий для меня, потому что плохих запросов много, спасибо.





Использование HttpWebRequest для новых разработок не рекомендуется Microsoft. Вместо этого вы должны использовать класс HttpClient, который значительно упрощает процесс.
Вот краткая оболочка, которую я создал, чтобы помочь вам начать работу.
public class HttpClientWrapper
{
private readonly HttpClient _httpClient;
public HttpClientWrapper(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<T> SendRequestAsync<T>(
string relativeUrl,
HttpMethod method,
object? payload,
IDictionary<string, string>? queryParameters,
IDictionary<string, string>? headers)
{
if (string.IsNullOrEmpty(relativeUrl))
{
throw new ArgumentNullException(nameof(relativeUrl));
}
string relativeUrlWithArguments = AddArgumentsToUrl(relativeUrl, queryParameters);
HttpRequestMessage requestMessage = CreateHttpRequestMessage(relativeUrlWithArguments, method, payload, headers);
var response = await _httpClient.SendAsync(requestMessage);
response.EnsureSuccessStatusCode();
var textResponse = await response.Content.ReadAsStringAsync();
if (string.IsNullOrEmpty(textResponse))
{
throw new InvalidOperationException("Empty response returned by server.");
}
T? data = JsonSerializer.Deserialize<T>(textResponse);
if (data == null)
{
throw new InvalidOperationException("Failed to deserialize the response to your model.");
}
return data;
}
private static string AddArgumentsToUrl(string url, IDictionary<string, string>? queryParameters)
{
queryParameters ??= new Dictionary<string, string>();
string argumentsString = string.Join("&", queryParameters.Select(arg => $"{arg.Key} = {arg.Value}"));
return !string.IsNullOrEmpty(argumentsString) ? $"{url}?{argumentsString}" : url;
}
private static HttpRequestMessage CreateHttpRequestMessage(string relativeUrl,
HttpMethod method,
object? payload,
IDictionary<string, string>? headers)
{
var httpRequestMessage = new HttpRequestMessage(method, relativeUrl)
{
Content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json")
};
if (headers != null)
{
foreach (var header in headers)
{
httpRequestMessage.Headers.Add(header.Key, header.Value);
}
}
return httpRequestMessage;
}
}
Простое использование класса выше может быть:
private static HttpClient httpClient = new HttpClient();
var httpClientWrapper = new HttpClientWrapper(httpClient);
var response = httpClientWrapper.SendRequestAsync<ResponseClass>(
relativeUrl: "http://myurl.com",
method: HttpMethod.Post,
payload: YourObjectThatWillBeSerializedToJson,
queryParameters: new Dictionary<string, string>
{
{ "query1", "value1" }
},
headers: new Dictionary<string, string>
{
{ "Accept", "AcceptValue" },
{ "Header2", "Header2Value" }
});
Где ResponseClass — это тип, в который будет десериализован ответ JSON. Для payload вы должны отправить свой объект, который будет сериализован в JSON. Параметры запроса и заголовки являются необязательными и могут быть переданы как словарь. Вы можете изменить функциональность этой оболочки по своему вкусу. Например, если вы хотите передать уже сериализованный JSON в качестве полезной нагрузки, вам придется немного изменить метод CreateHttpRequestMessage.
Важное примечание: рекомендуется использовать IHttpClientFactory для управления экземплярами HttpClient. Я создал статический HttpClient в своем примере, что тоже может подойти. Но важная часть здесь заключается в том, чтобы НЕ создавать новый экземпляр HttpClient для каждого вашего запроса.
Привет, сэр, я попробую, однако могу ли я узнать причину или какое-либо сравнение, говорящее о том, почему Microsoft рекомендует не использовать HttpWebRequest для новой разработки.
catch (WebException e)-> почему бы вам не прочитать ответ в улове и не посмотреть, что сервер говорит о вашем запросе?